[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [xml-dev] Validate XML selectively
From: "Badri Lakshmiraghavan" <lb2628@yahoo.com>
> Hi
>
> I'm using MS-XML4 to schema validate XML. Is it
> possible to validate an element depending upon the
> value of another element in XML. For example, if
> <COUNTRY> tag has the value US, <STATE> needs to be
> validated against schema definition for <STATE>. If
> not whatever value <STATE> holds should be let through
> without validation. Is it possible? Thanks in advance.
No.
These are sometimes called "co-occurrence constraints",
and W3c's XML Schemas does not support selecting types based on
values of elements or attributes.
What W3C's XML Schemas does support is to annotate your
schema with other "application-specific" information. You use
the <annotation><appinfo>...</appinfo></annotation> pattern.
The main schema language which can be embedded is
the Schematron language. There are open source XSLT
scripts to extract and generate the appropriate schemas.
These are also available in a GUI version for free from
http://www.topologi.com/ in a tool that uses MSXML 4
(which seems to be an excellent library.)
If you look on this list at Eddie Robertsson's post today
"Re: [xml-dev] tricky validation problem w multiple schemas"
it gives examples of embedding Schematron schemas in W3C's XML Schemas.
The only trick is that you will probably have to strength reduce the type for
STATE to include all possibilities, which would probably be a NMTOKEN.
Assuming that COUNTRY and STATE are siblings in
any order and that COUNTRY is required, add the following
annotation to the declaration for the COUNTRY element
<xs:annotation>
<xs:appinfo>
<sch:pattern name="FixState"
xmlns:sch="http://www.ascc.net/xml/schematron">
<sch:rule context="STATE/../COUNTRY/='US'">
<sch:assert test="STATE='AL' or STATE='CA' or ..."
>If the country is US, the state must be AL, CA ...</sch:assert>
</sch:rule>
<sch:rule context="STATE/../COUNTRY/='AU'">
<sch:assert test="STATE="ACT' or STATE='NSW' or ..."
>If the country is US, the state must be ACT, NSW ...</sch:assert>
</sch:rule>
<sch:rule context="STATE/../COUNTRY/='HP'">
<sch:assert test="STATE="Bliss' or STATE='Nirvana' or ..."
>If the country is Hippyland, the state must be Bliss, Nirvana, Fecklessness, ...</sch:assert>
</sch:rule>
</sch:rule>
</sch:pattern>
</xs:appinfo>
</xs:annotation>
This assumes no namespaces are used.
Cheers
Rick Jelliffe