我正在创建一个XML模式,描述来自各种来源的XML聚合。这些源具有各种/未知的元素名称,但我想验证已知的常见子元素。
E.g:
<foo>
<common bar="bar" />
</foo>
<baz>
<common bar="bar" />
</baz>
我想描述带有必需参数common
的{{1}}元素,但不知道示例中父元素的名称(bar
和foo
,但可能是现实中的任何事情)
我有以下内容,但不知道如何在任何元素中强制执行baz
元素。
common
W3C文档告诉我,您无法在<xs:complexType name="vendor">
<xs:sequence>
<xs:any namespace="##any" minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
标记中放置xs:sequence
标记,因此我不知道如何继续。
答案 0 :(得分:2)
在一般情况下,使用XSD 1.0无法实现这一点;除非: - 公共元素始终是第一个元素,在这种情况下,您首先设置该元素,然后按照xsd:any跟随它 - 公共元素位于命名空间中,可以相对于xsd表示的命名空间子句单挑出来:任何考虑你的命名空间,在这种情况下你可以在强制{{1}之前和之后使用任意数量的xsd:any实例。
或者,如果你留下minOccurs = 1,请将processContents设置为lax,并确保在验证期间XSD处理器可以使用common
的模式,那么至少可以保证{{1}发生,它是有效的。不幸的是,你不能保证它至少会出现一次。
如果以上都不适合您,那么您可以轻松定义Schematron附件到您的XSD 1.0;如果您能负担XSLT运行,这应该可行。
最后,如果XSD 1.1是一个选项,一个简单的断言将完全符合您的需要。问题在于XSD 1.1在支持方面仍处于起步阶段。
答案 1 :(得分:0)
首先,定义声明公共元素common
的模式。
然后,在文档中的common
元素上调用模式验证器,而不是在文档的最外层元素上调用。只有当您的验证器允许您说明从哪里开始验证时,这才有效;大多数使用API的验证器可以做到这一点,但许多命令行界面不支持它(它们应该,但它们不应该支持)。
或者,在“宽松通配符模式”中调用最外层文档元素上的模式验证器;这是(据我所知)最常见的命令行界面默认调用模式。只有当您的验证器通过降级到匹配通配符的元素的子节点(然后是子节点,然后进一步...)来处理宽松通配符时才会起作用,以寻求递归地验证它们。 (此行为在XSD 1.0中是可选的,但已广泛实施。)