Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

how to construct XSD to validate SI units and non-SI units

Status
Not open for further replies.

chuckhunt

Programmer
Jan 25, 2008
1
GB
hi all

i'm having xml trouble; i'm not a total beginner, but i'm neither is this my day job -- it's just a small offshoot of something i'm working on for a personal project. i'm sure someone else has already resolved this issue but googling hasn't helped me find a viable solution.

essentially i *think* i'm looking for how to do "if-then" in XSD.
though i may just be going about it the wrong way.

i'm creating an xsd schema which, among other things, has data values that are defined (or not) using Basic SI units; or derived SI units, or context dependent etc.

so it will allow elements that look like this:

(i paste it below first as entities, and then further below as characters)


<data>
<value>34</value>
<unit symbol="C" type="basicSI">Celsius</unit>
</data>

(where if "basicSI" is the type, then symbol MUST come from a prearranged selection; but if "contextDependent" is the type, then any symbol is validatable, as below:)

<data>
<value>24</value>
<unit symbol="mySymbol" type="contextDependent">myUnit</unit>
</data>

now, *if* someone selects type="basicSI" then i want to restrict the symbol attribute they can use; but *if* they select type="contextDependentUnits" then they should be able to use any symbol they like.

at the moment i have the XSD as below, but this restricts all symbol attributes to the basicSI values.

is there a way to do "if-then"? i can't seem to get it to work with xsd:choice

i'd be grateful for any pointers!

thanks

charles

below is an extract from my xsd:

the extract from the xsd was:

<xsd:element minOccurs="0" maxOccurs="1" name="unit">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="symbol">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Gy" />
<xsd:enumeration value="pH" />
<xsd:enumeration value="Bq" />
<xsd:enumeration value="mol" />
.....
...../
<xsd:enumeration value="K" />
<xsd:enumeration value="s" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="type" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="basicSI" />
<xsd:enumeration value="derivedSI" />
<xsd:enumeration value="conversionBasedUnits" />
<xsd:enumeration value="derivedUnits" />
<xsd:enumeration value="contextDependentUnits" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>

<data>
<value>34</value>
<unit symbol="C" type="basicSI">Celsius</unit>
</data>

<data>
<value>24</value>
<unit symbol="mySymbol" type="contextDependent">myUnit</unit>
</data>

<xsd:element minOccurs="0" maxOccurs="1" name="unit">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="symbol">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Gy" />
<xsd:enumeration value="pH" />
<xsd:enumeration value="Bq" />
<xsd:enumeration value="mol" />
.....
...../
<xsd:enumeration value="K" />
<xsd:enumeration value="s" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attribute name="type" use="optional">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="basicSI" />
<xsd:enumeration value="derivedSI" />
<xsd:enumeration value="conversionBasedUnits" />
<xsd:enumeration value="derivedUnits" />
<xsd:enumeration value="contextDependentUnits" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>


a
 
[0] First off, the treatement of unit of measure and conversion in all generality is an enormous task. You can google xsd and uom as a start to appreciate the work thrown in.

[0.1] But for a schema as a contract between limited parties using xml as a media of data exchange, the task should be focused to get thing done with certain loosely understood as "business logic". That can become somewhat manageable.

[1] As to the approach outlined (it's already quite involved), I would say it is too much to handle in the wxsl. There, it put the co-occurrence constraints at the central stage, and wxsl is vulnerable to fail. (In that case, you've to prepare to counter the mind-set of some that wxsl is the "standard". It is not - in this particular aspect. Alternative schema languages are actually received by the community open-arms.)

[2] That said, what to do within wxsl? I would say, you can make analogy to look up table approach in xslt. You could open up a section in the xml to define a "lookup table" of quantity units. Such as this.

<root>
<units>
<celsius description="Celsius" symbol="C" type="basicSI" />
<electronvolt description="Electron Volt" symbol="eV" type="basicSI" />
<pH description="Potential of Hydrogen" symbol="pH" type="derivedSI" /> <!-- type is what, I'm not sure. -->
<!-- etc etc -->
</units>
<!-- business below -->
</root>

[2.1] In the above, the unit name is actually constructed as the name of an element, rather than a common name like "unit" and put "celsius" for instance as an attribute value, name="celsius". The reason is that you can validate a fix element like "celsius" with fixed attribute values, just like fixed text value.

[2.2] The correspondance element name "celsius" with symbol attribute "C" can be done in the construction of celsius's element.

[2.3] The attribute type can be of type restricted from base="xs:string" with enumeration... (as you seem using...)

[2.4] The attribute symbol can then must be constraint to be unique over all children of <units> (using functionality available to orthodox wxsl, namely, xs:unique, xs:key, xs:keyref ...)

[2.5] With the above, the units elements can be constructed with xs:all, as the appearence of the element should appear at most once anyhow. By using xs:all, the order is free and up to the scripter.

[3] Then how about the business transaction?

[3.1] The data can be scripted something like this.
[tt]
<data>
<value uom="C">34</value>
</data>
[/tt]
[3.2] Here, uom must match one of the entry in the lookup table's symbol. This is again got done with xs:key, xs:keyref etc. This is doable.

[4] The above is a sketch of one resolution to get it done without the co-occurrence constraint holding up an approach within wsxl pure.

[5] One can argue that it seems that the approach suffers from the undue influence of wxml. Influence on the scripter's approach, it is fine. The problem is that it is influence by the weak-spot of wxsl, not its virtue! Free-mind is thereby unduely constraint. No wonder alternative schemas should not be viewed as side interest. As far as validation is concerned, they are of equipotential with and fair competitors of, or even more appropriate than wxsl.

[6] The lookup table part can furthermore be placed in its own namespace which can be imported. A lookup table can be enormous in size and complexity.

The above are some random thoughts and sketch of a practical approach. To fully put in place of a schema, it is not a small task even for a couple of uom involved between the interested transacting parties.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top