OASIS Mailing List ArchivesView the OASIS mailing list archive below
or browse/search using MarkMail.

 


Help: OASIS Mailing Lists Help | MarkMail Help

 


 

   Re: [xml-dev] Element validation based on attribute value? XMLSchema +

[ Lists Home | Date Index | Thread Index ]

Hi Andrzej,

> A simple example is using units of measure specified in an attribute in the
> following example: 
>
> <myElement uom="meters">2.5</myElement>
> <myElement uom="feet">9.0</myElement>
>
> Now assume I want to validate the myElement is always <= 3 meters
> (regardless of the unit of measure.....so it's less than roughly 11
> feet).
>
> There is no way to do this using just a  XMLSchema that I am aware of. 

Rick Jelliffe's commented about using other schema languages to fulfil
this requirement, but if you're still at the stage of designing your
markup language, you could design it so that XML Schema *can*
articulate this constraint, using the xsi:type attribute instead. The
instance document would look like:

<myElement xsi:type="meters">2.5</myElement>
<myElement xsi:type="feet">9.0</myElement>

So the 'uom' attribute would be replaced by the xsi:type attribute
(you could make it so that the uom attribute is present as well as the
xsi:type attribute, if you wanted).

To make an XML Schema for this, create an abstract simple type, based
on xs:decimal, called 'length' or something else appropriate. You can
put any restrictions you have on all types of length in here; for
example, if you want them to have a maximum of two decimal places:

<xs:simpleType name="length" abstract="true">
  <xs:restriction base="xs:decimal">
    <xs:fractionDigits value="2" />
  </xs:restriction>
</xs:simpleType>

The fact that this is an abstract type means that any element of the
length type must use xsi:type to indicate a subtype that its content
actually validates against. So if you do:

<xs:element name="myElement" type="length" />

then the myElement element is forced to have an xsi:type attribute.

You then just need to create non-abstract subtypes of the length type,
called meters and feet, which have the appropriate maxInclusive
facets:

<xs:simpleType name="meters">
  <xs:restriction base="length">
    <xs:maxInclusive value="3" />
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="feet">
  <xs:restriction base="length"
    <xs:maxInclusive value="9.84" />
  </xs:restriction>
</xs:simpleType>

The main problem with this approach is that you don't get to keep the
instance document looking like you want it to look - it's implicit
that the xsi:type attribute gives the name of the unit of measure that
you're using. As I said, you could always have a uom attribute as
well, but that introduces redundant information.

Another issue is that the xsi:type attribute is only one attribute,
but you might actually want to control several aspects of the value
through it. As a simple example, say that your ideal would be a size
attribute, containing 'short' for 1m max, 'medium' for between 1 and
2m and 'long' for over 2m. So you'd have:

<myElement uom="meters" size="short">0.5</myElement>
<myElement uom="feet" size="long">9.0</myElement>

The xsi:type equivalent would be something like:

<myElement xsi:type="short-meters">0.5</myElement>
<myElement xsi:type="long-feet">9.0</myElement>

Naturally, you need one type definition for each possible combination
of meta-attributes, so this gets quite unwieldy if you find you need
to add multiple such constraints.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/





 

News | XML in Industry | Calendar | XML Registry
Marketplace | Resources | MyXML.org | Sponsors | Privacy Statement

Copyright 2001 XML.org. This site is hosted by OASIS