The <Value>_<Unit> problem

Hi all,

If you remember a couple of weeks ago we had some queries about how you
could specify an element or attribute value that contains both a _value_
and a _unit_. For example I want to specify a document with products and
one of my child elements is productCost. I want the value of productCost
to be a space separated pair of values like:

<productCost>20 AUD</productCost>
<productCost>10 USD</productCost>
etc.

The suggested solution I had at the time was to create an enumerated
simpleType of all the currencies like this:

 <xsd:simpleType name="myCurrency">
  <xsd:restriction base="xsd:string">
   <xsd:enumeration value="AUD"/>
   <xsd:enumeration value="USD"/>
   <xsd:enumeration value="SEK"/>
  </xsd:restriction>
 </xsd:simpleType>

Then you create a myUnion datatype to be a Union of xsd:integer and
myCurrency:

 <xsd:simpleType name="myUnion">
  <xsd:union memberTypes="xsd:integer myCurrency"/>
 </xsd:simpleType>

Now you create a List type that is derived from the productCostType and
put the facet length="2" as a restriction:

 <xsd:simpleType name="productCostType">
  <xsd:restriction>
   <xsd:simpleType>
    <xsd:list itemType="myUnion"/>
   </xsd:simpleType>
   <xsd:length value="2"/>
  </xsd:restriction>
 </xsd:simpleType>

Now you have a datatype that allows for values like the above.

<productCost>20 AUD</productCost>
<productCost>10 USD</productCost>

The problem is that it also allows the reversed values:

<productCost>AUD 20</productCost>
<productCost>USD 10</productCost>

However, yesterday when checking the datatypes spec on another issue I
saw that a List datatype actually can have a pattern facet. This means
we can actually restrict our datatype to validate only the correct
values by applying the pattern:

<xs:pattern value="/d+ .+"/>   <!-- One or more digits (integer)
followed by a space followed by one or more characters. -->

So, the productCostType would be:

 <xsd:simpleType name="productCostType">
  <xsd:restriction>
   <xsd:simpleType>
    <xsd:list itemType="myUnion"/>
   </xsd:simpleType>
   <xsd:length value="2"/>
   <xs:pattern value="/d+ .+"/>
  </xsd:restriction>
 </xsd:simpleType>

The only validator that seems to support this is MSXML4 July release but
according to my reading of the spec this should be allowed.

Cheers,
/Eddie

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

 <xs:simpleType name="myCurrency">
  <xs:restriction base="xs:string">
   <xs:enumeration value="AUD"/>
   <xs:enumeration value="USD"/>
   <xs:enumeration value="SEK"/>
  </xs:restriction>
 </xs:simpleType>

 <xs:simpleType name="myUnion">
  <xs:union memberTypes="xs:integer myCurrency"/>
 </xs:simpleType>

 <xs:simpleType name="productCostType">
  <xs:restriction>
   <xs:simpleType>
    <xs:list itemType="myUnion"/>
   </xs:simpleType>
   <xs:length value="2"/>
   <xs:pattern value="\d+ .+"/>
  </xs:restriction>
 </xs:simpleType>

 <xs:element name="Root">
  <xs:complexType>
   <xs:sequence>
    <xs:element name="Child" type="productCostType"
maxOccurs="unbounded"/>
   </xs:sequence>
  </xs:complexType>
 </xs:element>

</xs:schema>

Received on Thursday, 2 August 2001 03:17:19 UTC