0

我发现了一些与 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:include 只是应该存在的元素的替代品,对吗?

谢谢,bp

4

2 回答 2

2

您为 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。

加上上面 cm-sperberg-mcqueen 所说的话。

如果您希望在进行 xinclude 扩展之前对其进行验证,那么您需要在模式中包含 xi:include 元素及其属性。

如果您希望它在执行 xinclude 扩展后验证,xinclude 处理器将(除非您以某种方式告诉它不要)通常将 xml:base 属性添加到包含的元素,因此您需要将 xml:base 添加为允许架构中的属性。(我最初以为,既然 xml 命名空间是保留的,那么 xml: 属性不需要包含在架构中,但事实并非如此。)

于 2013-08-10T04:55:11.063 回答
1

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

于 2013-02-10T19:01:51.240 回答