繁体   English   中英

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 的更改:

  1. 添加以下NS:
<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">
  1. 修改XSD如下:
    <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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM