在xml文档中简单使用xinclude

时间:2013-02-09 20:10:29

标签: xml xsd xinclude

我发现了一些与xinclude相关的问题,但没有一个专门解答我关于如何包含外部文档的基本问题

以下是一些我想互相引用的xml文档:

<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://test test-schema.xsd"
    xmlns:t="http://test">

    <t:first-name>Wilma</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/TR/xinclude" href="fred.xml"/>
    </t:spouse>

    </t:person>

<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://test test-schema.xsd"
 xmlns:t="http://test">
    <t:first-name>Fred</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/TR/xinclude" href="wilma.xml"/>
    </t:spouse>
</t:person>

和架构:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://test"
    targetNamespace="http://test" elementFormDefault="qualified"> 

<xs:element name="person" type="personType"/>


<xs:complexType name="personType">
    <xs:sequence>
        <xs:element name="first-name" type="xs:string"/>
        <xs:element name="last-name" type="xs:string"/>
        <xs:element name="spouse" type="personType"/>
    </xs:sequence>
</xs:complexType>

</xs:schema>

xi:include元素即将失效。我一直在寻找,找不到像这样的简单例子。 xi:只包括一个应该存在的元素的替身,对吗?

感谢, bp的

2 个答案:

答案 0 :(得分:1)

想要执行验证和XInclude处理的人可能希望首先执行XInclude,然后验证,或首先验证,然后执行XInclude,或先验证,然后执行XInclude处理,然后再次验证。在当前的思维阅读技术状态下,如果没有人类的帮助,软件无法分辨出哪些是理想的。你知道你希望事情发生的顺序,但是你告诉过你的软件吗?根据您的描述,听起来好像您的处理器默认为validate-first,然后执行XInclude;如果你想要一个非默认的处理顺序,你必须告诉你的处理器。你如何做到这一点取决于处理器;阅读文档。

答案 1 :(得分:1)

您的Xinclude名称空间错误。

在任一xml文件上运行xmllint --xinclude不会产生任何变化 因为它不被认为是xinclude语句。

将名称空间更改为:xmlns:xi="http://www.w3.org/2001/XInclude"

它会对输出进行一些更改,但您也会收到错误 在相互递归上:

$xmllint --xinclude wilma.xml 
fred.xml:8: element include: XInclude error : detected a recursion in wilma.xml
<?xml version="1.0" encoding="UTF-8"?>
<t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://test" xsi:schemaLocation="http://test test-schema.xsd">
    <t:first-name>Wilma</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <t:person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://test" xsi:schemaLocation="http://test test-schema.xsd">
    <t:first-name>Fred</t:first-name>
    <t:last-name>Flintstone</t:last-name>
    <t:spouse>
        <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="wilma.xml"/>
    </t:spouse>
</t:person> 
    </t:spouse>
</t:person>

XInclude应该递归处理xincludes,但是根据http://www.w3.org/TR/xinclude/#loops

  

当递归处理xi:include元素时,处理另一个xi:include元素是一个致命错误,该元素包含已在包含链中处理的包含位置和xpointer属性值。

此外,当你尝试根据模式验证它时,除了递归错误之外,你得到:

fred.xml:4: element person: Schemas validity error : Element '{http://test}person': This element is not expected. Expected is ( {http://test}first-name ).
wilma.xml fails to validate

我相信这是因为你的架构说配偶IsA personType,但在你的xml中, 配偶包含personType元素:person。

再加上c-m-sperberg-mcqueen上面所说的话。

如果你想在进行xinclude扩展之前验证它,那么你需要包括 xi:include元素及其在模式中的属性。

如果你想在进行xinclude扩展后验证它,那么xinclude处理器将会 (除非你告诉它不要以某种方式)通常添加一个xml:base属性 包含元素,因此您需要在模式中添加xml:base作为allowed属性。 (我最初认为,因为xml命名空间是保留的,所以xml:attributes 并不需要包含在架构中,但事实并非如此。 )