[英]How to make child element attributes required based on parent element attribute in xsd
[英]Conditionally make the child element value length validation based on the parent attribute name in XSD
我需要驗證以下 XML:
<nodes>
<node>
<tag name="id">
<value>345</value>
</tag>
<tag name="client">
<value>test</value>
</tag>
<tag name="section">
<value>test2</value>
</tag>
<tag name="token">
<value>79467</value>
</tag>
</node>
</nodes>
在這里,屬性名稱是固定的。 根據名稱,某些字段的值可以為空,而某些字段是必需的。 例如,如果屬性名稱是 token,則子元素可以具有空值。 我目前擁有的 XSD 是(基於 XSD 1.0):
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="nodes">
<xs:complexType>
<xs:sequence>
<xs:element ref="node" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="node">
<xs:complexType>
<xs:sequence>
<xs:element name="tag" maxOccurs="unbounded" type="tagType" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:unique name="TagUniquenessCheck">
<xs:selector xpath="tag"/>
<xs:field xpath="@name"/>
</xs:unique>
</xs:element>
<xs:complexType name="tagType">
<xs:sequence>
<xs:element name="value">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="id"/>
<xs:enumeration value="client"/>
<xs:enumeration value="section"/>
<xs:enumeration value="token"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:schema>
這 XSD 強制所有子元素值不為空(最小長度條件為 1)。 我知道不可能在 XSD 1.0 上進行條件分配。 我試過 XSD 1.1。 以下是我添加到 XSD 的更改:
<xs:schema elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1">
<xs:simpleType name="mandatory">
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="optional">
<xs:restriction base="xs:string">
<xs:minLength value="0"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="tagType">
<xs:sequence>
<xs:element name="value" type:"xs:string">
<xs:alternative test="@name = token" type="optional"/>
<xs:alternative test="@name != token" type="mandatory"/>
</xs:element>
</xs:sequence>
<xs:attribute name="name" use="required">
<xs:simpleType>
<xs:restriction base="xs:NMTOKEN">
<xs:enumeration value="id"/>
<xs:enumeration value="client"/>
<xs:enumeration value="section"/>
<xs:enumeration value="token"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
這似乎不起作用。 感謝在 XSD 上完成此條件分配的任何幫助。
要使用條件類型分配,您需要使tag
元素的類型以其屬性值為條件。 就像是
<xs:element name="tag">
<xs:alternative test="@name ='id'" type="idTagType"/>
<xs:alternative test="@name ='client'" type="clientTagType"/>
...
</xs:element>
<xs:complexType name="idTagType">
...
</xs:complexType>
<xs:complexType name="clientTagType">
...
</xs:complexType>
如果需要,您可以使不同的 xxTagType 定義全部繼承自抽象超類型。
順便說一句,還有另一種驗證這種經常被忽視的結構的方法,如果您希望它與 XSD 1.0 一起使用,這種方法特別有用。 那就是將您的驗證編寫為(轉換 -> 驗證)管道,其中轉換步驟將結構轉換為類似以下內容:
<nodes>
<node>
<id>345</value>
<client>test</value>
<section>test2</value>
<token>79467</value>
</node>
</nodes>
這更容易驗證(對於后續處理也更容易)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.