【问题标题】:Parsing XML references in Delphi在 Delphi 中解析 XML 引用
【发布时间】:2010-11-27 13:14:55
【问题描述】:

我使用 Delphi 2006 数据绑定向导为 XML 配置文件创建接口。后来我意识到 XML 的一些重复部分可以从主文件中分离出来并在需要的地方引用。生成的 XML 如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module [
<!ENTITY Schema65 SYSTEM "schemas/65.xml">
]>
<module>
  <schema>&Schema65;</schema>
</module>

如果我使用 Internet Explorer 打开此文件,占位符“&Schema65;”的内容正确替换为外部文件的内容。然而,Delphi 解析器似乎无法识别此功能并且不会替换文本。知道如何解决这个问题吗?

【问题讨论】:

  • 您使用的是哪个解析器。 TXmlDocument 支持许多不同的解析器。

标签: xml delphi delphi-2006


【解决方案1】:

Internet Explorer 肯定在使用 MSXML 库。将TXmlDocument.DomVendor 属性设置为MSXML_DOM(在msxmldom 单元中找到),您应该会得到相同的行为。您还可以将DefaultDOMVendor 全局变量更改为SMSXML,以使所有新的TXmlDocument 对象都使用该供应商。

【讨论】:

  • 谢谢 Rob,您的回答很有帮助,但并不能解决我的问题。我希望得到与使用带有 MSXML_DOM 的 Internet Explorer 相同的结果,但事实并非如此。解析器仍然不包含引用的文件。我尝试了 Delphi 中可用的其他解析器,但没有成功。
【解决方案2】:

您是否已经尝试过OmniXML?我已经使用它多年了,它总能解决我关于 XML 文件的问题。如果您还没有,我建议您试一试:它使用简单、轻便且免费。

【讨论】:

    【解决方案3】:

    Internet Explorer 使用XmlResolver,XmlDocument 类使用 XmlDocument 的 XmlResolver 属性来定位 XML 数据中未内联的资源,例如外部文档类型定义 (DTD)、实体和架构。这些项目可以位于网络或本地驱动器上,并且可以通过统一资源标识符 (URI) 进行识别。这允许 XmlDocument 解析文档中存在的 EntityReference 节点并根据外部 DTD 或架构验证文档。

    您应该使用一个 delphi 库来实现外部资源的解析器和解析器。

    Open XML 使用 TStandardResourceResolver 实现解析器

    再见。

    【讨论】:

    • 默认解析器有一个名为“ParseOptions”的属性并将其设置为“poResolveExternals”使其查找外部引用(如果找不到文件,我会收到错误消息)。但是,占位符不会被外部内容替换。关于如何使解析器也替换内容的任何想法?我认为这会解决我的问题。
    【解决方案4】:

    以下解决了我的问题。似乎 Delphi 默认解析器 (MSXML) 实际上包含外部实体引用,但以某种奇怪的方式。对于这个例子

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE module [
    <!ENTITY Schema65 SYSTEM "schemas/65.xml">
    ]>
    <module>
      <schema>&Schema65;</schema>
    </module>
    

    我假设创建一个 TXMLDocument 并且外部文件包含一个简单的文本,我可以像这样获取文件的内容:

    MyXML := TXMLDOcument.Create(myfile.xml);
    ExternalText := MyXML.documentElement.ChildNodes['schema'].Text;
    

    如果实体引用被替换为简单文本,这实际上是有效的。但是,在使用外部实体的情况下,Delphi 将在“模式”节点内创建一个类型为“ntEntityRef”的新子节点。该节点还将有一个最终包含我期望的简单文本的子节点。文本可以像这样访问:

    MyXML.documentElement.ChildNodes['schema'].FirstChild.FirstChild.Text;
    

    如果外部实体文件包含节点结构,将在实体引用节点内部创建相应的节点。确保 TXMLDocument.ParseOptions 至少设置为 [poResolveExternals] 才能发生。这种方法还可以相对轻松地调整 XML 数据绑定向导生成的代码以使用外部实体。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多