【问题标题】:Parsing XML using document() which includes references in XSLT使用包含 XSLT 引用的 document() 解析 XML
【发布时间】:2013-06-05 09:51:48
【问题描述】:

这是我的问题。

我有一个使用引用并包含其他 XML 文件的 XML 文件

XML 文件(由 XSL 解析):

<?xml version="1.0" encoding="utf-8"?>
<!ENTITY % references SYSTEM "myref.ref">
<test>
    <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="file2.XML"/>
</test>

文件2.XML:

<?xml version="1.0" encoding="utf-8"?>
<action>&testref;</action>

myref.ref:

<!ENTITY  testref 'cool ref there'>

XSL:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:apply-templates select="//test"/>
</xsl:template>

<xsl:template match="test">
    <xsl:for-each select="document('file2.XML')//action">
    [...]
</xsl:template>

然后我有一个 XSL,它使用 document() 函数打开 file2.XML,其中包括引用(在 myref.ref 中引用)。

因此,当我使用 document('file2.XML') 时,我收到一条错误消息,指出实体“reventity”已被引用但未声明。

当我使用 document() 打开其他 XML 时,如何使用 myref.ref ?

谢谢。

【问题讨论】:

  • 您使用哪个 XSLT 处理器,以及(更重要的是)您使用哪个底层 XML 解析器?像 expat 这样的非验证解析器可能不会解析外部实体,即使使用验证解析器,出于安全原因,这些功能有时也会默认禁用。
  • 我已经尝试使用 Xalan 和 Saxon XSLT 处理器,但我遇到了同样的错误。我在转换过程中没有使用任何底层 XML 解析器,问题应该出在 XSL 中。外部 XML 文件已正确读取。如果我没有任何引用,它可以正常工作。
  • 能否与我们分享您的 XML 文件和 XSLT 文件。
  • 您的 XSLT 处理器不解析 XML 本身,它使用 XML 解析器。如果您使用 Saxon(9.5?),您是否尝试过使用命令行选项 saxonica.com/documentation/html/using-xsl/commandline.html,例如 -dtd:(on|off|recover)?而且您的示例令人困惑,它有DOCTYPE doctype,这意味着XML 的根元素名称应该是doctype,但您有xi:include。您可以发布所有文件的最小但完整的示例来重现问题吗?我目前不确定您在哪些文件中有 DOCTYPE 以及在哪个错误中。
  • @NavinRawat xml 已经存在,XSLT 在 file2.XML 上使用 document() 函数,file2.XML 只是块内的引用。在参考文件中只有一个参考。这个错误正是我在帖子中写的。

标签: xml xslt reference xinclude


【解决方案1】:

您描述为“XML 文件(由 XSL 解析)”的文件不是 XML;如果实体声明包含在文档类型声明中,它将是 XML,但现在不是。如果您的 XSLT 处理器没有抱怨,我假设您处理的不是您所展示的,而是更像

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test [
<!ENTITY % references SYSTEM "myref.ref">
]>
<test>
  <xi:include 
    xmlns:xi="http://www.w3.org/2001/XInclude" 
    href="file2.XML"/>
</test>

XInclude specification 指定默认情况下包含的资源被解析为好像它们具有 MIME 类型 application/xml;它明确地使 DTD 处理的性能或非性能不受约束。如果 XInclude 处理器确实对其执行 DTD 处理,我希望它使用 XInclude 目标的 DTD,而不是包含 XML 文档的 DTD。也就是说,考虑到显示的输入,如果任何 XInclude 处理器确实做了您希望的事情,我会感到惊讶。我系统上的 libxml 副本只是引发了您提到的错误,抱怨未定义实体“testref”。

另一方面,我不得不承认,很难说你想要的东西显然与 XInclude 规范不兼容。毕竟,规范明确指出“是否执行 DTD 或 XML 模式验证的细节……不受本规范的约束”。鉴于该声明,很难争辩说 XInclude 规范要求对包含资源的任何 DTD 处理都使用包含资源的 DTD 而不是包含资源的 DTD 执行。 DTD 处理不受 XInclude 规范的约束;我没有办法证明希望将包含的资源解析为外部实体是错误的。当然,同样的道理,当 xmllint 抱怨未声明的实体时,它显然是在其作为合格处理器的权利范围内。

由于 XInclude 的设计显然是为了使外部实体变得不必要,因此决定解析包含的资源,就好像它们是外部实体一样,这将是一个非常不寻常的实现。 (如果包含的资源有自己的 DTD,这样的处理器会做什么?发出错误?执行回退处理?)无论对错,我怀疑你会在这里找到任何 XInclude 处理器来做你想做的事情;如果我是你,我会重新考虑我的设计。

【讨论】:

  • XSLT document() 函数的问题不在于 XInclude 吗?
  • 对我来说似乎是 XInclude 问题。
猜你喜欢
  • 2015-08-02
  • 2019-07-17
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-19
  • 2012-10-14
相关资源
最近更新 更多