执行此操作的最简单方法(或者在我看来是这样!其他人可能不同意)是使用稍微不同的 XML 结构。您需要一个主地址和零个或多个非主地址。如果您对具有不同要求的事物使用不同的名称,那么任何 XML 验证方法(DTD、XSD 等)都可以很容易地说出来。如果 XML 结构变成
<addresses>
<primary-address>
<street>One str.</street>
<number>111</number>
</primary-address>
<address>
<street>Two str.</street>
<number>222</number>
</address>
</addresses>
那么很容易编写一个 XSD 模式,该模式限制addresses
为只包含一个主地址,并明确捕获主地址和其他地址具有相同结构的事实:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xsd:complexType name="address">
<xsd:sequence>
<xsd:element ref="street"/>
<xsd:element ref="number"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name="primary-address" type="address"/>
<xsd:element name="address" type="address"/>
<xsd:element name="addresses">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="primary-address"/>
<xsd:element ref="address" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="mixed" mixed="true">
<xsd:sequence/>
</xsd:complexType>
<xsd:element name="street" type="mixed"/>
<xsd:element name="number" type="mixed"/>
</xsd:schema>
如果您无法更改 XML 结构,或者不想更改,您可以切换到 XSD 1.1 并使用断言来强制执行约束,或者您可以使用 Schematron 来执行此操作。
或者(这是一个有点脏的技巧),你可以说(1)属性的唯一合法值primary
是true
,(2)属性在元素上是可选的address
,以及(3)属性的每次出现都primary
必须有一个独特的价值。
但我真的建议更改 XML 结构。