これを行う最も簡単な方法(または私にはそう思われます!他の人は同意しないかもしれません)は、わずかに異なるXML構造を使用することです。1つのプライマリアドレスと0個以上の非プライマリアドレスが必要です。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>
addresses
次に、プライマリアドレスを1つだけ含むように制約し、プライマリアドレスと他のアドレスが同じ構造を持っているという事実を明示的にキャプチャするXSDスキーマを簡単に作成できます。
<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)属性は要素上でオプションであり、(3)属性address
の各出現は持っている必要があると言うことができますprimary
一意の値。
ただし、XML構造を変更することを強くお勧めします。