简体   繁体   中英

Make content of element unique in xsd

I have an element:

<xsd:element name="tags" type="tagsType"></xsd:element>

This is tagsType :

<xsd:complexType name="tagsType">
        <xsd:sequence>
            <xsd:element name="t" minOccurs="0" maxOccurs="unbounded">
                <xsd:complexType>
                    <xsd:simpleContent>
                        <xsd:extension base="xsd:string">
                            <xsd:attribute name="tagname" type="xsd:string"></xsd:attribute>
                        </xsd:extension>
                    </xsd:simpleContent>
                </xsd:complexType>
                <xsd:key name="tagKey">
                    <xsd:selector xpath="tags/tag"/>
                    <xsd:field xpath="@tagname"/>
                </xsd:key>
            </xsd:element>
        </xsd:sequence>
</xsd:complexType>

How I have restricted tagname attribute to be unique, but I want to make content of that tag also unique. Example:

<tags>
    <t>tag1</t>
    <t>tag1</t>
    <t>tag2</t>
</tags>

This should not validate, because of duplicate tag1 . This should validate:

<tags>
    <t>tag1</t>
    <t>tag2</t>
    <t>tag3</t>
</tags>

How do I achieve this?

You can achieve the desired result with the following XSD.
It uses the xsd:unique element to make sure that the values are unique.

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:complexType name="tagsType">
        <xsd:sequence>
            <xsd:element name="t" type="xsd:string"  minOccurs="0" maxOccurs="unbounded" />
        </xsd:sequence>
    </xsd:complexType>
    
    <xsd:element name="tags" type="tagsType">
        <xsd:unique name="t_unique" >
            <xsd:selector xpath="t"/>
            <xsd:field xpath="."/>
        </xsd:unique>
    </xsd:element>
    
</xsd:schema>

This XSD validates the second XML and fails on the first one.


The xsd:unique element has two sub-elements:

The xsd:unique element MUST contain the following (in order):

  • one and only one xsd:selector element (contains an XPath expression that specifies the set of elements across which the values specified by field must be unique)
  • one or more xsd:field elements (contains an XPath expression that specifies the values that must be unique for the set of elements specified by the selector element)

If you want every X in a Y to have a unique value for Z, then:

(a) the declaration of Y should hold the xs:unique constraint

(b) the selector should be a path expression that selects X starting at Y

(c) the field should be a path expression that selects Z starting at X.

So the fundamental mistake you've made is to define the constraint at the wrong level. xs:unique doesn't belong on the thing you want to be unique, it belongs on the containing element within which it needs to be unique.

That's because the validity of an element depends only on its content, and not on its context. If two X's have the same value for Z, it's the containing Y that's invalid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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