global key/unique attribute in xsd

1.2k Views Asked by At

I am trying those days to find a way to create a global attribute that will be used by all the elements in the schema and will serve as a key/unique attribute to them a well. look a the next example:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" 
attributeFormDefault="unqualified" targetNamespace="http://www.NameSpace/Family" xmlns:tns="http://www.NameSpace/Family">
<xs:attribute name="id" type="xs:string"/>
<xs:complexType name="parentType">
  <xs:sequence>
    <xs:element name="Name" type="xs:string"/>
    <xs:element name="Child" type="tns:childType" minOccurs="1" maxOccurs="unbounded"/>
  </xs:sequence>  
  <xs:attribute ref="tns:id" use="required"/>  
</xs:complexType>  
<xs:complexType name="childType">
  <xs:sequence>
    <xs:element name="Name" type="xs:string"/>
  </xs:sequence>  
  <xs:attribute ref="tns:id" use="required"/>  
</xs:complexType>
<xs:element name="Family">  
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Parent" type="tns:parentType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
</xs:schema>

now lets say for example, I create 1 parent with 2 kids, I want do define a key/unique on the id attribute so that all the elements id's (parents an childs) will be different from each other.

2

There are 2 best solutions below

0
imhotap On BEST ANSWER

You can declare id as having type xsd:ID like this:

<xs:attribute name="id" type="xs:ID"/>

Then you reference the declared attribute (like you already do):

<xs:complexType name="parentType">
...
  <xs:attribute ref="tns:id" use="required"/>
</xs:complexType>

You could also just declare the id attribute on the types or elements directly.

The xs:ID type imposes ID semantics globally on all ID-declared attributes in a document.

1
Michael Gunter On

To create a key, use the <xs:key> element. In your case, you want to establish a key across a set of elements that is within the <Family> element. Therefore, your key would be within the <xs:element> tag that defines Family.

<xs:element name="Family">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="Parent" type="tns:parentType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <!-- SOMETHING LIKE THIS WILL DO -->
  <xs:key name="id">
    <xs:selector xpath="tns:Parent|tns:Parent/tns:Child" />
    <xs:field xpath="@tns:id" />
  </xs:key>
</xs:element>

You could also use <xs:unique> instead of <xs:key>. The only difference between the two is that <xs:unique> allows the field to be optional. In your case, where your id attribute is required by definition of the schema, there would be no difference using either <xs:unique> or <xs:key>.