XML Schema validation with schematron

This should cover W3C XML Schema, Relax NG and DTD related problems.
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

XML Schema validation with schematron

Post by andregm »

hi all,
I'm new with XML language and I'm analysing if it woth the work to use or not this file format.
I'm want to use XML Schemas and instance (.xml) to represent metadada information upon system... since my analysis and specification is quite complex I'm posting a little example of my problem (which very lower than the original :roll: )
I allready anderstand xml format and xml schemas but i'm totally awhere of xml schematron :(
my problem here (so far...) is to validate not a xml instance but make a validation upon a xml schema: i must use a xml schematron right?
the example is quite simple:

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="XPTO">
<xs:annotation>
<xs:documentation>XML Schema example</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Set1">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Set2">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Set3">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
this schema allows 3 mandatory set, each of them can have a list of none or infinite string...

what i want to validate here is that each list must be exclusive: none of the element that appear on one of the set can appear on any other one of the instance!
for example:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<XPTO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C:\Documents and Settings\André G. Marques\Desktop\myExample\xpto.xsd">
<Set1>
<Element>"aaa"</Element>
<Element>"bbb"</Element>
<Element>"ccc"</Element>
<Element>"ddd"</Element>
</Set1>
<Set2>
<Element>"aaa"</Element>
<Element>"bbb1"</Element>
</Set2>
<Set3>
<Element>"aaa"</Element>
<Element>"ddd2"</Element>
</Set3>
</XPTO>
is not valid since it got the string element "aaa" repeated at least in 2 list...
is it possible to validate? must i use schematron??

best regards,

aGM.
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

The logic is quite simple...
all i have to do is validate/check the elements of the first with the element of the others, doing this recursively, it is not necesary to perform the last valoidation i.e. the last set will never validate with the others since it have been allready checked :roll:
but i really don't know how it can be done....
thx again...
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

No, you do not need Schematron for that. You just need to add a unique constraint as below, see the xs:unique at the end of the schema:

Code: Select all


<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="XPTO">
<xs:annotation>
<xs:documentation>XML Schema example</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="Set1">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Set2">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Set3">
<xs:complexType>
<xs:sequence>
<xs:element name="Element" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:unique name="uniqueElement">
<xs:selector xpath=".//Element"/>
<xs:field xpath="."/>
</xs:unique>
</xs:element>
</xs:schema>
Best Regards,
George
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

I will try it!
thx u!
i will feedback u soon i hope!
best regards,
aGM
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

i see that u used xpath... it is possible to use xpath only to validate the first and second? for example:
set_1:
{a,s,d}

set_2:
{a}

set_3:
{a,s,d,f,g}

not ok because of the conflict of set_1 with set_2
but:
set_1:
{a,s,d}

set_2:
{f,g}

set_3:
{a,s,d,f,g}

sould be fine since set is independent from the other set...
or sould i put the set 1 and 2 in an independent level?

thx for u time,
aGM
sorin_ristache
Posts: 4141
Joined: Fri Mar 28, 2003 2:12 pm

Post by sorin_ristache »

Hello,

Just change the unique constraint to:

Code: Select all

      <xs:unique name="uniqueElement">
<xs:selector xpath="Set1/Element | Set2/Element"/>
<xs:field xpath="."/>
</xs:unique>
Regards,
Sorin
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

thx u George and Sorin!
I see that xpath is also very powerfull...
I will try to use the proposed solution to my particular case...
once again, thank u!
aGM
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

:oops:
One more thing... in my model i'm using some complex type elements
for example instead of

Code: Select all


 <Set1>
<Element>"aaa"</Element>
</Set1>
i got

Code: Select all


 <Set1 type ="xpto" >
<Element>"aaa"</Element>
</Set1>
my problem is that in

Code: Select all


  <xs:unique name="uniqueElement">
<xs:selector xpath="Set1/Element | Set2/Element"/>
<xs:field xpath="."/>
</xs:unique>
i must specify the path

Code: Select all


  <xs:unique name="uniqueElement">
<xs:selector xpath="Set1 type ="xpto"/Element | Set2 type ="xpto"/Element"/>
<xs:field xpath="."/>
</xs:unique>
and as u can guess the " in "xpto" isn't very welcome from the validator...
the return error is somtehing like
the fields "." of identity 'Set1' must evaluate to a qualified node set
remark that i got this error since i only put

Code: Select all


...
<xs:selector xpath="Set1/Element | Set2/Element"/>
...
instead of "something" like

Code: Select all


...
<xs:selector xpath="Set1 type ="xpto"/Element | Set2 type ="xpto"/Element"/>
...
i guess...
then, i tried:

Code: Select all


...
<xs:selector xpath="Set1 type ="xpto" | ...
...
but in vain, unfortunately... somehow i was hoping that last one would work.. but no :s
does xs:selector only work with "basic types" and don't with complex types?
and again... i simplified too much my example with the "set example" since that each one can have themselves "complex types"... (i.e. composed type )... i didn't know that this will bring so much trouble... :?
have i any solution without modifying my Schema?
thx,
aGM
george
Site Admin
Posts: 2095
Joined: Thu Jan 09, 2003 2:58 pm

Post by george »

Hi,

The values for selector and field xpath attribute belong to a reduced set of XPath expressions as defined in the XML Schema specification. Anyway what you tried is not even valid XPath. Basically you cannot make name tests in the reduced XPath accepted in the identity constraints in XML Schema, so you cannot test for a Set1 element that has a specific attribute with some specific value.
If you want to place such constrains then you can go back to the initial idea and use Schematron embedded rules inside the XML Schema. Check out the oXtgen/samples/schematron examples, you can find there XML Schemas with Schematron embedded rules.
See also
http://www.oxygenxml.com/forum/ftopic1664.html#5297

Best Regards,
George
andregm
Posts: 7
Joined: Thu Apr 27, 2006 3:50 pm

Post by andregm »

thx ;)
i will try then!
Best regards,
aGM
Post Reply