[英]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.