首页 > 解决方案 > 如何使用 MSXML6 解析 DTD 节点结构

问题描述

我想在我的 Delphi 应用程序中使用 MSXML6 解析一些独立的 DTD 文件。DTD 文件内容类似于:

<!ELEMENT note (to,from,heading,body)>

<!ELEMENT to (#PCDATA)>
<!ATTLIST to
  type CDATA #FIXED "email"
  default CDATA #FIXED "you@foo.bar"
>

<!ELEMENT from (#PCDATA)>
<!ATTLIST from
  type CDATA #FIXED "email"
  default CDATA #FIXED "me@foo.bar"
>

<!ELEMENT heading (#PCDATA)>
<!ATTLIST heading
  type CDATA #FIXED "string"
>

<!ELEMENT body (#PCDATA)>
<!ATTLIST body
  type CDATA #FIXED "string"
>

尝试使用 MSXML 加载此数据失败,并显示错误消息“不能在 DTD 之外有 DTD 声明”。

将 DTD 包装到一些 DOCTYPE 元素中时,如下所示:

<?xml version="1.0"?>
<!DOCTYPE note [
... content of DTD file above ...
]>
<note/>

解析器成功,但不允许迭代 DTD 结构。加载和显示文档的 (Delphi) 代码如下所示:

var
   XmlDoc : iXmlDomDocument2;
   i : integer;
begin
   XmlDoc := CoDomDocument60.Create();
   XmlDoc.SetProperty('NewParser', FALSE);
   XmlDoc.SetProperty('ProhibitDTD', FALSE);
   XmlDoc.Async := FALSE;
   XmlDoc.ValidateOnParse := FALSE;

   XmlDoc.Load(FileName);
   if ( XmlDoc.ParseError.ErrorCode <> 0 ) then
       raise Exception.Create(XmlDoc.ParseError.Reason);

   // This will display "note"
   ShowMessage('DocType: ' + XmlDoc.Doctype.Name);
   // This will display the embedded DTD as a string
   ShowMessage('DTD: ' + XmlDoc.Doctype.Xml);

   // These loops will display nothing
   for i := 0 to XmlDoc.Doctype.Entities.Length-1 do
      ShowMessage('Entity: ' + XmlDoc.Doctype.Entities[i].NodeName);
   for i := 0 to XmlDoc.Doctype.Notations.Length-1 do
      ShowMessage('Notation: ' + XmlDoc.Doctype.Notations[i].NodeName);
   for i := 0 to XmlDoc.Doctype.ChildNodes.Length-1 do
      ShowMessage('Child: ' + XmlDoc.Doctype.ChildNodes[i].NodeName);
end;    

有没有办法使用 MSXML6 迭代 DTD 节点结构?

标签: delphidtdmsxmlmsxml6dtd-parsing

解决方案


推荐阅读