49

Lets say I have a schema that defines the following XML:

<Values>
    <Add Key="Key1">Value 1</Add>
    <Add Key="Key2">Value 2</Add>
    <Add Key="Key3">Value 3</Add>
    <Add Key="Key4">Value 4</Add>
</Values>

I would like, at a schema level, to be able to enforce that the values for the Key attribute are unique, i.e. the example above is valid, but the following example would be invalid:

<Values>
    <Add Key="Key1">Value 1</Add>
    <Add Key="Key2">Value 2</Add>
    <Add Key="Key2">Value 3</Add>
    <Add Key="Key3">Value 4</Add>
</Values>

Notice that there are two Add elements with a Key of Key2

For reference here is the simple schema:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xs:element name="Values">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Add" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:simpleContent>
                            <xs:extension base="xs:string">
                                <xs:attribute name="Key" type="xs:token" use="required"/>
                            </xs:extension>
                        </xs:simpleContent>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

I am under the impression that this is not possible at a schema level, however I am all ears.

3 Answers 3

66

@BatteryBackupUnit has the right idea, but the syntax is more like:

<xs:element name="Values">
  <xs:complexType>
    <xs:sequence>
      <xs:element ref="Add" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
  <xs:unique name="UniqueAddKey">
    <xs:selector xpath="Add" /> 
    <xs:field xpath="@Key" /> 
  </xs:unique>
</xs:element>
4
  • please more explanation, didn't get it, I mean just put the xml produced by this schema
    – Tarek
    Commented Aug 17, 2013 at 13:52
  • 1
    What kind of explanation are you looking for? An XSD tutorial that explains xs:unique? You can surely find that in any decent book or tutorial on XSD. Commented Aug 17, 2013 at 16:46
  • Should that be <xs:element ref="Add" maxOccurs="unbounded"/> ? Commented Mar 2, 2016 at 2:44
  • 2
    You could provide links and a brief description. I guess I could summit an edit when I fully understand the usage of unique. Cheers. Commented Jan 8, 2018 at 23:03
8

More on Michael Kay's answer: If your schema (XSD) declares a namespace, you must include this in your selection.xpath. If you are using Microsoft Visual Studio 2010, you may find a namespace automatically declared.

<xs:schema id="MyData"
    targetNamespace="http://tempuri.org/MyData.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/MyData.xsd"
    xmlns:mstns="http://tempuri.org/MyData.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
    ...
    <xs:unique name="UniqueAddKey">
        <xs:selector xpath="mstns:Add" /> 
        <xs:field xpath="@Key" /> 
    </xs:unique>
</xs:schema>
6

you can achieve this by using xs:unique

<xs:element name="Instrument">
  <xs:complexType>
   <xs:all>
    <xs:unique name="ModuleId">
      <xs:selector xpath="./*" /> 
      <xs:field xpath="@id" /> 
    </xs:unique>
   </xs:all>
  </xs:complexType>
</xs:element>

The above example will enforce a unique attribute "id" for all Instrument Elements. there's also xs:key, which can be used to establish a Primary Key - Foreign Key relationship: http://www.datypic.com/books/defxmlschema/chapter17.html

Not the answer you're looking for? Browse other questions tagged or ask your own question.