bluearth
bluearth

Reputation: 523

Restrict single attribute usage in sequence using XML Schema

Supposing the following instance document:

<person>
  <name>Maurice Moss</name>
  <addresses>
    <address current="true">441 Wallaby way</address>
    <address>2 Mercer Road</address>
  </addresses>
</person>

Using XML Schema, is it possible to enforce that only one <address> element can have it's current attribute set to "true" within the sequence.

Cheers

NOTE: I'm not quite sure how to phrase this problem, so I hope anyone having better idea can fix the title or place relevant tags.

Upvotes: 0

Views: 517

Answers (2)

RichardTowers
RichardTowers

Reputation: 4762

At least partly possible using <xsd:unique/>:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="person">
        <xs:complexType>
            <xs:all>
                <xs:element name="name"/>
                <xs:element name="addresses">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="address" maxOccurs="unbounded">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="xs:string">
                                            <xs:attribute name="current" type="xs:boolean"/>
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                    <!-- HERE -->
                    <xs:unique name="onlyOneCurrentAddress">
                        <xs:selector xpath="address"/>
                        <xs:field xpath="@current"/>
                    </xs:unique>
                    <!-- /HERE -->
                </xs:element>
            </xs:all>
        </xs:complexType>
    </xs:element>
</xs:schema>

This would prevent multiple current="true" attributes, but unfortuantely also multiple current="false", so you may want to adapt it a bit.

Upvotes: 0

Michael Kay
Michael Kay

Reputation: 163458

I think using XSD 1.0 you can enforce that there is only one element with a "current" attribute, as RichardTowers shows, but you cannot allow multiple "current" attributes of which only one may be true.

You can do this of course in XSD 1.1 using assertions:

<xs:assert test="count(address[@current='true']) eq 1"/>

(or count(...) le 1 if that's what was intended).

Upvotes: 1

Related Questions