说我有以下xml文档:
<root xmlns:p="uri:myNamespace">
<p:tagA>
<p:tagB />
</p:tagA>
</root>
tagB必须只能在tagA中。我可以编写一个xsd来验证:
<xsd:schema ... targetNamespace="uri:myNamespace" elementFormDefault="qualified">
<xsd:element name="tagA">
<xsd:complexType>
<xsd:element name="tagB" type="..." />
</xsd:complexType>
</xsd:element>
</xsd:schema>
现在出现了问题:我想忽略外部命名空间之间的任何标记:
<root xmlns:p="uri:myNamespace">
<p:tagA>
<whatever />
<foo>
<bar>
<p:tagB />
</bar>
</foo>
</p:tagA>
</root>
正如您所看到的,tagB现在嵌套在没有名称空间的其他标签中。
是否有可能(如何?)编写一个XSD,它仍然强制我名称空间中tagA
内的唯一标记是tagB
但是其间可能有其他名称空间的标记?
答案 0 :(得分:0)
XSD(以及DTD和Relax NG)中用于约束元素内容的内容模型定义了儿童的合法序列;它们在无上下文语法中像单个生产规则一样工作。可以将后代限制在更深层次,但它需要一个不间断的声明链:在您的示例中,当foo
和bar
出现在p:tagA
元素内时,您需要声明它们,以确保它们之间只包含一个p:tagB
元素。但是你的出发点是你不想限制这些元素。
所以:你不能使用内容模型来表达你想到的约束。
在XSD 1.1中,您可以使用附加到p:tagA
元素的断言来要求它在其后代(p:tagB
)中精确地包含count(.//p:tagB) eq 1
元素。但是,您不能使用附加到p:tagB
的断言来要求它仅出现在p:tagA
元素中:断言可以在树中向下看,但不能向上看。 (如果您知道保证存在的容器的名称,则可以在该容器上使用断言,断言每个p:tagB元素都包含在ap:tagA元素中,使用类似count(.//p:tagA//p:tagB) eq count(.//p:tagB)
的断言。)< / p>
某些但不是所有XSD验证器目前都支持XSD 1.1。