Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specify a unique constraint for attributes using the <xs:unique> as a child element of the <xs:element> tag?

If I have the following element spec in XSD I can add the <xs:unique> constraint as a child of <xs:element name="Parent"> but I can't get it to work as a child of <xs:element name="Child">:

<xs:element name="Parent">
  <xs:complexType>
    <xs:element name="Child" minOccurs="0" maxOccurs="unbounded">
      <xs:complexType>
        <xs:attribute name="Key" type="xs:string" use="required" />
      </xs:complexType>

      <!-- Option A: insert unique constraint here with selector . -->

    </xs:element>
  </xs:complexType>

  <!-- Option B: insert unique constraint here with selector ./Child -->

</xs:element>

This is the unique constraint that works as a child of <xs:element name="Parent">:

<xs:unique name="ChildKey">
  <xs:selector xpath="./Child"/>
  <xs:field xpath="@Key" />
</xs:unique>

But this unique constraint doesn't work as a child of <xs:element name="Child">:

<xs:unique name="ChildKey">
  <xs:selector xpath="."/>
  <xs:field xpath="@Key" />
</xs:unique>

Do I need to change the selector XPath in the second case?

like image 574
Michiel van Oosterhout Avatar asked Feb 22 '23 21:02

Michiel van Oosterhout


1 Answers

If you think about it, the selector "." will always return the current node; the selector gives you a node set with one node only... So, within a set with one node only, the uniqueness is guaranteed, since an attribute with a given name can only happen once. This should explain why you cannot get it the way you think it should work.

When you set it at the parent level, it works because you are now enforcing uniqueness among a set of Child nodes.

In database terms, a constraint such as what you need can only be defined at the table level. This is what it would look like (I've rewritten the XSD slightly to get a good E/R out of it).

XSD:

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns:tns="http://tempuri.org/XMLSchema.xsd" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Parent" type="Parent">
        <xs:unique name="ParentKey">
            <xs:selector xpath="tns:Child"/>
            <xs:field xpath="@Key"/>
        </xs:unique>
    </xs:element>
    <xs:complexType name="Parent">
        <xs:sequence>
            <xs:element name="Child" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="Key" type="xs:string" use="required"/>
                </xs:complexType>
                <xs:unique name="ChildKey">
                    <xs:selector xpath="."/>
                    <xs:field xpath="@Key"/>
                </xs:unique>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

XSD Diagram:

enter image description here

The equivalent ADO.NET E/R:

enter image description here

An XML showing errors:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<Parent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
    <Child Key="Key1"/>
    <Child Key="Key1"/>
</Parent>

Error message:

Error occurred while loading [], line 5 position 3
There is a duplicate key sequence 'Key1' for the 'http://tempuri.org/XMLSchema.xsd:ParentKey' key or unique identity constraint.
Unique.xml is invalid.
like image 134
Petru Gardea Avatar answered Apr 08 '23 05:04

Petru Gardea