Daniel Kelleher
Daniel Kelleher

Reputation: 15

XSD: Defining a Restriction on ID type with Union

I am trying to restrict an attribute with type ID to a union of two types:

<attribute name="metaDataID" use="required">
  <simpleType>
    <union>
      <simpleType>
        <restriction base="ID">
          <enumeration value="from" />
          <enumeration value="to" />
          <enumeration value="cc" />
          <enumeration value="bcc" />
          <enumeration value="subject" />
          <enumeration value="sendTime" />
        </restriction>
      </simpleType>
      <simpleType>
        <restriction base="ID">
          <pattern value="attachment\d+-metadata" />
        </restriction>
      </simpleType>
    </union>
  </simpleType>
</attribute>

So the basic idea is the attribute value should either match the enumeration {from/to/cc/bcc/subject/sendTime} or the pattern "attachment\d+-metadata".

When validating using JAXB I get the following error:

The attribute use 'metaDataID' in this type has type 'null', which is not validly derived from 'ID', the type of the matching attribute use in the base type.

This makes sense to me. The new definition of metaDataID no longer has type ID. However I cannot specify a type on the simpleType or union elements, so I don't know how to specify that the result of the union is also of type ID. I have also tried:

<attribute name="metaDataID" use="required">
  <simpleType>
    <restriction base="ID">
      <union>
        ...
      </union>
    </restriction>
  </simpleType>
</attribute>

but restrictions do not allow unions underneath them. Is this even possible?

Upvotes: 0

Views: 831

Answers (2)

Michael Kay
Michael Kay

Reputation: 163342

I am trying to restrict an attribute with type ID to a union of two types:

In general a union of two types that are both restrictions of some type T is not itself considered to be a restriction of T. This is nothing particularly to do with T being xs:ID.

I tried this schema:

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:simpleType name="u">
    <xs:union>
      <xs:simpleType>
        <xs:restriction base="xs:positiveInteger">
          <xs:enumeration value="1"/>
        </xs:restriction>
      </xs:simpleType>  
      <xs:simpleType>
        <xs:restriction base="xs:positiveInteger">
          <xs:enumeration value="2"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:union>
  </xs:simpleType>

  <xs:element name="e" type="xs:positiveInteger"/>

  <xs:element name="f" type="u" substitutionGroup="e"/>

</xs:schema>

and Saxon reports:

Error on line 21 of test.xsd:
  Element f cannot be in the substitution group of e. Type u is not validly derived from type xs:positiveInteger

I can't think of a good reason why it's not considered a valid restriction: probably just an oversight in the spec. But that's the way it is.

Upvotes: 0

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

Reputation: 25034

XSD 1.0 is a little obscure when it comes to the enforcement of ID constraints on types derived from ID; I would expect the behavior of processors on examples like this one to vary from implementation to implementation.

You might get better results if you abandoned the union and derived your desired type in a single restriction step using a more complex pattern:

  <simpleType>
    <restriction base="ID">
      <pattern value="from" />
      <pattern value="to" />
      <pattern value="cc" />
      <pattern value="bcc" />
      <pattern value="subject" />
      <pattern value="sendTime" />
      <pattern value="attachment\d+-metadata" />
    </restriction>
  </simpleType>

XSD 1.1 is (I think) a bit more explicit. So you might also get better results if you can use an XSD 1.1 processor.

Upvotes: 1

Related Questions