简体   繁体   English

XSD中根据父属性名有条件地做子元素值长度校验

[英]Conditionally make the child element value length validation based on the parent attribute name in XSD

I need to validate the following XML:我需要验证以下 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>

Here, the attributes names are fixed.在这里,属性名称是固定的。 Based on the the names, value can be empty for certain fields while it's required for certain fields.根据名称,某些字段的值可以为空,而某些字段是必需的。 Ex, if the attribute name is token, the child element can have empty value.例如,如果属性名称是 token,则子元素可以具有空值。 The XSD currently I have is (based on XSD 1.0):我目前拥有的 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>

This XSD forces, all the child element value to be not empty (having minlength condition as 1).这 XSD 强制所有子元素值不为空(最小长度条件为 1)。 I understood that it's not possible to do conditional assignments on XSD 1.0.我知道不可能在 XSD 1.0 上进行条件分配。 I have tried with XSD 1.1.我试过 XSD 1.1。 Following is the change that I added to XSD:以下是我添加到 XSD 的更改:

  1. Add the following NS:添加以下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. Modify the XSD as follows:修改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>


This doesn't seem to work.这似乎不起作用。 Appreciate any help to do this conditional assignment on XSD.感谢在 XSD 上完成此条件分配的任何帮助。

To use conditional type assignment, you need to make the type of the tag element conditional on the value of its attributes.要使用条件类型分配,您需要使tag元素的类型以其属性值为条件。 Something like就像是

<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>

You can make the different xxTagType definitions all inherit from an abstract super type if you want.如果需要,您可以使不同的 xxTagType 定义全部继承自抽象超类型。

Incidentally, there's another way of validating this kind of structure that is often overlooked, which is particularly useful if you want it to work with XSD 1.0.顺便说一句,还有另一种验证这种经常被忽视的结构的方法,如果您希望它与 XSD 1.0 一起使用,这种方法特别有用。 That is to write your validation as a (transform -> validate) pipeline, where the transformation step converts the structure to something like:那就是将您的验证编写为(转换 -> 验证)管道,其中转换步骤将结构转换为类似以下内容:

<nodes>
   <node>
      <id>345</value>
      <client>test</value>
      <section>test2</value>
      <token>79467</value>
   </node>
</nodes>

which is much easier to validate (and much easier for subsequent processing as well).这更容易验证(对于后续处理也更容易)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何基于XSD中的父元素属性制作所需的子元素属性 - How to make child element attributes required based on parent element attribute in xsd XSD-根据父元素中的属性值验证属性值 - XSD - Validate attribute value based on attribute value in parent element XSD验证-如果存在父元素,则将子元素设为必需,否则将子元素设为可选 - XSD validation - Make child element as Mandatory if the Parent Element is Present, Else Make the Child Optional XSD:使用XSD根据元素的属性值控制xml元素的长度限制 - XSD:Controlling the restriction on length of xml element based on that element's attribute value using XSD 基于父元素的XML XSD验证? - XML XSD validation based on parent element? 如何根据子代和父代的属性更改子代元素的值? - How to change value of child element based on attribute of child and parent? XSD 子元素的数据类型取决于父元素的属性 - XSD data type of child element depending on parent element's attribute XSD:孩子的名字是父母的名字 - XSD: Child's name is the name of parent's attribute 如何在xsd模式中定义XML元素以使所有子元素具有相同的属性值? - How to define XML element in xsd schema to make all child elements to have same attribute value? XSD:将element的属性值约束为父属性的子字符串 - XSD: constrain attribute value of element to a substring of parent attribute
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM