有我的问题。
我有一个使用引用的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>
file2.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>
然后我有一个使用document()函数打开file2.XML的XSL,其中包含引用(在myref.ref中引用)。
所以当我使用document('file2.XML')时,我得到一个错误,说实体“refentity”被引用,但未被声明。
当我用document()打开其他XML时,如何使用myref.ref?
感谢。
答案 0 :(得分: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处理器做你想做的事情;如果我是你,我会重新考虑我的设计。