nahab
nahab

Reputation: 1354

Restrict attribute value to child attribute (reference existing value)

I have a xml like this:

<userCredentials default="user1" >
    <userCredential username="user1" password="pwd" />
    <userCredential username="user2" password="pwd" />
    <userCredential username="user3" password="pwd" />
</userCredentials>

How can I resrict value of attribute default to be only one of //userCredential[@username] value?

Below my xsd scheme:

<xs:complexType name="userCredential">
  <xs:attribute name="username" type="xs:string" use="required" />
  <xs:attribute name="password" type="xs:string" use="required" />
</xs:complexType>    

<xs:complexType name="userCredentials">
  <xs:sequence>
    <xs:element name="userCredential" type="tns:userCredential" minOccurs="1"
                maxOccurs="unbounded" />
  </xs:sequence>
  <xs:attribute name="default" use="required" >
      <xs:simpleType>
        <xs:restriction>
          <xs:pattern value="" />
        </xs:restriction>
      </xs:simpleType>
  </xs:attribute>        
</xs:complexType>  

Upvotes: 3

Views: 3627

Answers (1)

Phrogz
Phrogz

Reputation: 303261

This is completely possible. Here's an example XSD that enforces the uniqueness of all usernames within the block and also requires that the default attribute references one of those values:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="userCredentials" type="CredsType">

    <!-- ensure all user names are unique -->
    <xs:unique name="uniqueUserNames">
      <xs:selector xpath="userCredential"/>
      <xs:field xpath="@username"/>
    </xs:unique>

    <!-- ensure that the `default` attribute references existing username -->
    <xs:keyref name="defaultNameRef" refer="userNames">
      <xs:selector xpath="."/>
      <xs:field xpath="@default"/>
    </xs:keyref>
    <xs:key name="userNames">
      <xs:selector xpath="./userCredential"/>
      <xs:field xpath="@username"/>
    </xs:key>
  </xs:element>

  <xs:complexType name="CredsType">
    <xs:sequence>
      <xs:element name="userCredential" type="UserCredentialType"
                  maxOccurs="unbounded" />
    </xs:sequence>
    <xs:attribute name="default" type="xs:NCName" />
  </xs:complexType>

  <xs:complexType name="UserCredentialType">
    <xs:attribute name="username" type="xs:NCName"/>
    <xs:attribute name="password" type="xs:string"/>
  </xs:complexType>
</xs:schema>

Upvotes: 8

Related Questions