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

我怕爱的太早我们不能终老 提交于 2019-12-03 21:23:35

问题


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?


回答1:


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:

The equivalent ADO.NET E/R:

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.


来源:https://stackoverflow.com/questions/8801645/how-can-i-specify-a-unique-constraint-for-attributes-using-the-xsunique-as-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!