Rui Sun
Rui Sun

Reputation: 33

XSD: Different Restriction by Attribute Values

I'm new in XSD and have the following question, thanks a lot for your help!

Suppose I have the xml:

<DataGroup>
  <Data name="name">Jane</Data>
  <Data name="age">50</Data>
  <Data name="state>MA</Data>
  <Data name="zipcode">01000</Data>
</DataGroup>

I'd like to put restriction on: when the attribute name equals to "age", the value of should be an integer and >20, when the attribute name equals to "state", the value of should be two letters. when the attribute name equals to "zip code", the value of should be \d{5}.

Can not modify the xml, any idea? Thanks!

Upvotes: 1

Views: 788

Answers (1)

helderdarocha
helderdarocha

Reputation: 23637

Using XSD 1.1 you can declare alternative types for each situation. Additionally you can restrict the number of <Data> elements to exactly four, and add an assertion to guarantee that each different attribute occurs exactly once:

<xs:element name="DataGroup">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="Data" maxOccurs="4" minOccurs="4">
                <xs:alternative type="NameData"  test="@name='name'" />
                <xs:alternative type="AgeData"   test="@name='age'" />
                <xs:alternative type="ZipData"   test="@name='zipcode'"/>
                <xs:alternative type="StateData" test="@name='state'"/>
            </xs:element>
        </xs:sequence>
        <xs:assert test="Data/@name='name' and Data/@name='age' and Data/@name='zipcode' and Data/@name='state'"></xs:assert>
    </xs:complexType>
</xs:element>

Since <Data> is a simple type, you need to declare the attribute as an extension of each type:

<xs:complexType name="NameData">
    <xs:simpleContent>
        <xs:extension base="xs:string">
            <xs:attribute name="name" type="xs:string"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
<xs:complexType name="AgeData">
    <xs:simpleContent>
        <xs:extension base="AgeType">
            <xs:attribute name="name" type="xs:string"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
<xs:complexType name="ZipData">
    <xs:simpleContent>
        <xs:extension base="ZipType">
            <xs:attribute name="name" type="xs:string"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType>
<xs:complexType name="StateData">
    <xs:simpleContent>
        <xs:extension base="StateType">
            <xs:attribute name="name" type="xs:string"/>
        </xs:extension>
    </xs:simpleContent>
</xs:complexType> 

The restrictions you declare in the types which are base for the simple types:

<xs:simpleType name="AgeType">
    <xs:restriction base="xs:integer">
        <xs:minExclusive value="20"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="StateType">
    <xs:restriction base="xs:string">
        <xs:pattern value="[A-Z]{2}"/>
    </xs:restriction>
</xs:simpleType>

<xs:simpleType name="ZipType">
    <xs:restriction base="xs:string">
        <xs:pattern value="\d{5}"/>
    </xs:restriction>
</xs:simpleType>

This will validate your file with the restrictions you require.

Upvotes: 1

Related Questions