是否可以添加新的XML标签以便它对XSD验证是透明的?
A具有描述XML对象(简化的示例)的XSD架构:是否可以添加新的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中有一个新的标签,以便它透明地“通过”验证(即完全忽略)?
我尝试添加在希望XSD验证会忽略它的XML一个新的命名空间,但是这并没有帮助:
<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有很强的验证。也许有另一种方法来做到这一点?
是的,没有。如果原始模式有一个特殊的标签,有一种方法可以实现这一点。
如果你事先知道文件可能有额外的元素,但你不提前知道这些元素,那么模式可以以向前兼容的方式使用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>
可以通过更改namespace
和processContents
属性的值来调整xs:any
的行为。
但是,如果模式已经完成,并且超出了您的控制范围,那么额外的元素只有在原始设计者允许的情况下才会出现。
一个例子是... XML Schema本身。 XML Schema元素可能包含外部名称空间中的任意属性(几种标准是以这种方式构建在XML Schema上的),这是因为Schema的XML Schema明确允许其他名称空间中的属性。
是的,我想过使用'xs:any'模式元素。但不幸的是,该模式已经在目标机器上,并且不升级应用程序版本就无法更改(由于特殊原因这是不可能的)。显然,原始的模式设计者不允许使用额外的元素...... – dymanoid
另一个答案是重构XML实例。 XML Schema允许在更大的实例中嵌套经过模式验证的XML(无需修改)。
<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>
这可以通过导入前者和引用元素my:item
的新模式来实现。
只要嵌套XML严格验证它,前面的模式不需要任何修改。
那么,如果我可以将新模式提供给应用程序用户,那将是可能的。但不幸的是,由于特殊原因,应用程序版本无法升级,所以我坚持使用旧版本。 – dymanoid
如果应用程序位于不同的名称空间中,应用程序如何查看该新项目?我相信如果没有架构修改,这是不可能的。 –
@AlexeyR,命名空间只是一个(不幸的)例子。实际上,我需要一种方法,使标签对XSD验证完全透明,而不会明确允许* undefined *标签。恐怕似乎是不可能的。 – dymanoid