XML Schema How to Restrict Attribute by Enumeration XML Schema How to Restrict Attribute by Enumeration xml xml

XML Schema How to Restrict Attribute by Enumeration


The numerical value seems to be missing from your price definition.Try the following:

<xs:simpleType name="curr">  <xs:restriction base="xs:string">    <xs:enumeration value="pounds" />    <xs:enumeration value="euros" />    <xs:enumeration value="dollars" />  </xs:restriction></xs:simpleType><xs:element name="price">        <xs:complexType>            <xs:extension base="xs:decimal">              <xs:attribute name="currency" type="curr"/>            </xs:extension>        </xs:complexType></xs:element>


New answer to old question

None of the existing answers to this old question address the real problem.

The real problem was that xs:complexType cannot directly have a xs:extension as a child in XSD. The fix is to use xs:simpleContent first. Details follow...


Your XML,

<price currency="euros">20000.00</price>

will be valid against either of the following corrected XSDs:

Locally defined attribute type

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">  <xs:element name="price">    <xs:complexType>      <xs:simpleContent>        <xs:extension base="xs:decimal">          <xs:attribute name="currency">            <xs:simpleType>              <xs:restriction base="xs:string">                <xs:enumeration value="pounds" />                <xs:enumeration value="euros" />                <xs:enumeration value="dollars" />              </xs:restriction>            </xs:simpleType>          </xs:attribute>        </xs:extension>      </xs:simpleContent>    </xs:complexType>  </xs:element></xs:schema>

Globally defined attribute type

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">  <xs:simpleType name="currencyType">    <xs:restriction base="xs:string">      <xs:enumeration value="pounds" />      <xs:enumeration value="euros" />      <xs:enumeration value="dollars" />    </xs:restriction>  </xs:simpleType>  <xs:element name="price">    <xs:complexType>      <xs:simpleContent>        <xs:extension base="xs:decimal">          <xs:attribute name="currency" type="currencyType"/>        </xs:extension>      </xs:simpleContent>    </xs:complexType>  </xs:element></xs:schema>

Notes

  • As commented by @Paul, these do change the content type ofprice from xs:string to xs:decimal, but this is not strictlynecessary and was not the real problem.
  • As answered by @user998692, you could separate out thedefinition of currency, and you could change to xs:decimal, butthis too was not the real problem.

The real problem was that xs:complexType cannot directly have a xs:extension as a child in XSD; xs:simpleContent is needed first.

A related matter (that wasn't asked but may have confused other answers):

How could price be restricted given that it has an attribute?

In this case, a separate, global definition of priceType would be needed; it is not possible to do this with only local type definitions.

How to restrict element content when element has attribute

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">  <xs:simpleType name="priceType">      <xs:restriction base="xs:decimal">        <xs:minInclusive value="0.00"/>        <xs:maxInclusive value="99999.99"/>      </xs:restriction>    </xs:simpleType>  <xs:element name="price">    <xs:complexType>      <xs:simpleContent>        <xs:extension base="priceType">          <xs:attribute name="currency">            <xs:simpleType>              <xs:restriction base="xs:string">                <xs:enumeration value="pounds" />                <xs:enumeration value="euros" />                <xs:enumeration value="dollars" />              </xs:restriction>            </xs:simpleType>          </xs:attribute>        </xs:extension>      </xs:simpleContent>    </xs:complexType>  </xs:element></xs:schema>


you need to create a type and make the attribute of that type:

<xs:simpleType name="curr">  <xs:restriction base="xs:string">    <xs:enumeration value="pounds" />    <xs:enumeration value="euros" />    <xs:enumeration value="dollars" />  </xs:restriction></xs:simpleType>

then:

<xs:complexType>    <xs:attribute name="currency" type="curr"/></xs:complexType>