Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XML Schema How to Restrict Attribute by Enumeration

Tags:

xml

xsd

I have the following XML Tag

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

How do I restrict the currency attribute to one the following:

  • euros
  • pounds
  • dollars

AND the price to a double?

I just get an error when I try to a type on both, here's what I've got so far:

<xs:element name="price">     <xs:complexType>         <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:complexType> </xs:element> 
like image 430
Luke Avatar asked Jan 19 '12 12:01

Luke


People also ask

What is enumeration in XML schema?

Enumerations are a base simple type in the XSD specification containing a list of possible values. Single-valued enumerations are shown as restrictions of the base simple type xs:token , as illustrated below: ? < xs:simpleType name=”GraduationPlanTypeMapType”>

Are XML attributes optional?

Defining XML Attributes An Attribute can appear 0 or 1 times within a given element in the XML document. Attributes are either optional or mandatory (by default they are optional). The "use" property in the XSD definition is used to specify if the attribute is optional or mandatory.

Which one defines the type of XML data and restrictions?

Overview of XSDAn XSD defines the structure of an XML document. It specifies the elements and attributes that can appear in an XML document and the type of data these elements and attributes can contain.


2 Answers

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> 
like image 194
user998692 Avatar answered Oct 01 '22 23:10

user998692


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 of price from xs:string to xs:decimal, but this is not strictly necessary and was not the real problem.
  • As answered by @user998692, you could separate out the definition of currency, and you could change to xs:decimal, but this 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> 
like image 33
kjhughes Avatar answered Oct 01 '22 21:10

kjhughes