是否可以添加新的XML标记,使其对XSD验证透明?

时间:2017-08-15 08:56:18

标签: xml xsd schema xml-validation

A有一个描述XML对象的XSD架构(简化示例):

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://my-custom-ns.com">
    <xs:element name="item">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="active" type="xs:boolean"/>
                <xs:element name="value" type="xs:string"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

该架构作为资源内置在应用程序中,并安装在许多工作站上。 该应用程序使用XML文件并根据此架构验证它们。 以下是这种XML的(简化)示例:

<my:item xmlns:my="http://my-custom-ns.com">
    <active>true</active>
    <value>foo</value>
</my:item>

现在,我希望我的XML文件在不更改XSD的情况下获取新元素(新标记):

<my:item xmlns:my="http://my-custom-ns.com">
    <active>true</active>
    <value>foo</value>
    <tag>bar</tag>
</my:item>

我没有更改XSD,所以显然新标签的验证失败了。 有没有办法在XML中使用新标记,以便它能够通过&#34;验证透明(即完全被忽略)?

我尝试在XML中添加一个新的命名空间,希望XSD验证会忽略它,但这没有帮助:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com">
    <active>true</active>
    <value>foo</value>
    <new:tag>bar</new:tag>
</my:item>

背景是:当前应用版本应该可以处理具有附加标记的XML文件,简单地忽略它。但是,如上所述,该应用程序对XSD进行了强有力的验证。也许有另一种方法可以做到这一点?

2 个答案:

答案 0 :(得分:0)

是和否。如果原始模式具有特殊标记,则有一种方法可以实现此目的。

如果您事先知道文档可能有额外的元素,但您事先并不知道这些元素,则可以使用xs:any标记以向前兼容的方式设计模式,如下所示:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://my-custom-ns.com">
    <xs:element name="item">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="active" type="xs:boolean"/>
                <xs:element name="value" type="xs:string"/>
                <xs:any namespace="##other" processContents="lax" minOccurs="0"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

本文档对上述架构有效:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com">
    <active>true</active>
    <value>foo</value>
</my:item>

以及这一个:

<my:item xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com">
    <active>true</active>
    <value>foo</value>
    <new:tag>bar</new:tag>
</my:item>

可以通过更改xs:anynamespace属性的值来调整processContents的行为。

但是,如果架构已经完成,并且超出了您的控制范围,则只有原始设计者允许时才会出现额外的元素。

这方面的一个例子是...... XML Schema本身。 XML Schema元素可能包含外部名称空间中的任意属性(有几种标准以这种方式构建在XML Schema上),这是因为Schema的XML Schema明确允许其他名称空间中的属性。

答案 1 :(得分:0)

另一个答案是重构XML实例。 XML Schema允许在更大的实例中嵌套经过模式验证的XML(无需修改)。

cat thesis.tex | aspell list --mode=tex -d en_US -p ./wordlist.txt | sort | uniq -u

这可以通过导入前一个模式并引用元素<new:wrapper xmlns:my="http://my-custom-ns.com" xmlns:new="http://new-ns.com"> <my:item> <active>true</active> <value>foo</value> </my:item> <new:tag>bar</new:tag> </new:wrapper> 的新模式来实现。

只要嵌套的XML严格对其进行验证,前一个模式就不需要任何修改。