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



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中有一个新标签,以便它透明地"通过"验证(即完全被忽略(?

我尝试在 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具有很强的验证,如上所述。也许还有另一种方法可以做到这一点?

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

如果您事先知道文档可能有额外的元素,但您事先不知道这些元素,则可以使用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>

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

但是,如果架构已完成,并且不受控制,则只有在原始设计器允许的情况下才能显示额外的元素。

这方面的一个例子是...XML 架构本身。XML 架构元素可以在外部命名空间中包含任意属性(以这种方式在 XML 架构上构建多个标准(,这是因为架构的 XML 架构显式允许其他命名空间中的属性。

另一种答案是重构 XML 实例。XML 架构允许在更大的实例中嵌套经过架构验证的 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 严格针对它进行验证即可。

最新更新