Set XSD duplicate constraint at document-level

时间:2015-05-24 20:43:03

标签: xml xsd xml-validation

I have the following XML:

<Movies>
    <Title>
        <Platform>Hulu</Platform>
        <PlatformID>50019855</PlatformID> <!-- Reject xml based on duplicate PlatformID -->
        <UnixTimestamp>1431892827</UnixTimestamp>
    </Title>
    <Title>
        <Platform>Hulu</Platform>
        <PlatformID>50019855</PlatformID> <!-- Reject xml based on duplicate PlatformID -->
        <UnixTimestamp>1431892127</UnixTimestamp>
    </Title>
</Movies>

The following XSD validates, however I want it to reject it because it has a duplicate PlatformID.

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xs:element name="Movies">
  <xs:complexType>

    <xs:sequence>
      <xs:element name="Title" maxOccurs="unbounded">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="Platform" type="xs:string"/>
            <xs:element name="PlatformID" type="xs:string" maxOccurs="unbounded"/>
            <xs:element name="UnixTimestamp" type="xs:positiveInteger"/>
          </xs:sequence>
        </xs:complexType>
      <xs:unique name="uniquePlatformID">
        <xs:selector xpath=".//Title/PlatformID"/>
        <xs:field xpath="."/>
      </xs:unique>

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

</xs:schema>

What would be the correct XSD here, to reject it based on the duplicate PlatformID above? What is wrong with the XSD I'm currently using? I believe the issue is that I'm trying to create a unique constraint within the Title node, whereas I need to create it document-wide at the Movies/Title/PlatformID level.

1 个答案:

答案 0 :(得分:1)

You were close. Just move the xs:unique up to be part of the definition of the root Movies element since the scope of uniqueness is intended to be across the entire document (within the root element, that is):

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Movies">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Title" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Platform" type="xs:string"/>
              <xs:element name="PlatformID" type="xs:string" maxOccurs="unbounded"/>
              <xs:element name="UnixTimestamp" type="xs:positiveInteger"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="uniquePlatformID">
      <xs:selector xpath="Title"/>
      <xs:field xpath="PlatformID"/>
    </xs:unique>
  </xs:element>
</xs:schema>

Then you'll get an error such as the following about duplicate values for PlatformID:

[Error] try.xml:11:42: cvc-identity-constraint.4.1: Duplicate unique value [50019855] declared for identity constraint "uniquePlatformID" of element "Movies".