By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,529 Members | 824 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,529 IT Pros & Developers. It's quick & easy.

XML Schema to describe specifc case

P: n/a
Hi,
How can I describe an XML like this:

<X>
<Y/>
<Z/>
<Y/>
<Y/>
</X>

I mean a case where Z appears once and Y appears zero or more times and
the order is not important. If Z might appear more than once I can use:

<xsi:choice minOccurs="0" maxOccurs="unbounded">

But I do not know what to do when it appears once.
Thanks,
Reuven Nisser
Mar 15 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Hi,

You need a model like:

Y*,Z,Y*

In XML Schema that will be:

<xs:element name="X">
<xs:complexType>
<xs:sequence>
<xs:element ref="Y" minOccurs="0" maxOccurs="unbounded"/>
<xs:element ref="Z"/>
<xs:element ref="Y" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Mar 15 '06 #2

P: n/a
Hi,
Thanks, I thought it will be the answer but I hoped there is an easier
way. You see Y could be several items (Y1,Y2,Y3...) which means creating
a "choice" before and after the Z element.
Regards, Reuven
Mar 15 '06 #3

P: n/a
Hi,
Thanks, I thought it will be the answer but I hoped there is an easier
way. You see Y could be several items (Y1,Y2,Y3...) which means creating
a "choice" before and after the Z element.

And if Z is also several items (Z1,Z2,Z3,...) which can also appear once
everywhere I have a problem.

The complete script would be:
<X>
<Y1/>
<Z2/>
<Y2/>
<Y1/>
<Z1/>
<Y2/>
<Y3/>
<Z3/>
</X>

Regards, Reuven
Mar 15 '06 #4

P: n/a
Hi,

You cannot do this in XML Schema alone, but you can use a relaxed model
in the XML Schema and embedded Schematron rules to check that Z1, Z2,
Z3 elements appear once. Below is a working XML Schema with embedded
schematron rules that does that:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="X">
<xs:annotation>
<xs:appinfo>
<pattern xmlns="http://www.ascc.net/xml/schematron" name="Check
number of occurances">
<rule context="X">
<assert test="count(Z1)=1">There should be one occurence of
Z1 in X.</assert>
<assert test="count(Z2)=1">There should be one occurence of
Z1 in X.</assert>
<assert test="count(Z3)=1">There should be one occurence of
Z1 in X.</assert>
</rule>
</pattern>
</xs:appinfo>
</xs:annotation>
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Y1"/>
<xs:element ref="Y2"/>
<xs:element ref="Y3"/>
<xs:element ref="Z1"/>
<xs:element ref="Z2"/>
<xs:element ref="Z3"/>
</xs:choice>
</xs:complexType>
</xs:element>
<xs:element name="Y1">
<xs:complexType/>
</xs:element>
<xs:element name="Y2">
<xs:complexType/>
</xs:element>
<xs:element name="Y3">
<xs:complexType/>
</xs:element>
<xs:element name="Z1">
<xs:complexType/>
</xs:element>
<xs:element name="Z2">
<xs:complexType/>
</xs:element>
<xs:element name="Z3">
<xs:complexType/>
</xs:element>
</xs:schema>

You can also do this in Relax NG. Below are working schemas both in
compact syntax and in XML syntax.

Compact syntax:

start =
element X {
(element Z1 { text }
& element Z2 { text }
& element Z3 { text })
& (element Y1 { text }
| element Y2 { text }
| element Y3 { text })*
}

XML syntax:

<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element name="X">
<interleave>
<interleave>
<element name="Z1"><text/></element>
<element name="Z2"><text/></element>
<element name="Z3"><text/></element>
</interleave>
<zeroOrMore>
<choice>
<element name="Y1"><text/></element>
<element name="Y2"><text/></element>
<element name="Y3"><text/></element>
</choice>
</zeroOrMore>
</interleave>
</element>
</start>
</grammar>

Best Regards,
George
---------------------------------------------------------------------
George Cristian Bina
<oXygen/> XML Editor, Schema Editor and XSLT Editor/Debugger
http://www.oxygenxml.com

Mar 15 '06 #5

P: n/a
Hi Reuven,

Must the Z element always appear beside between Y blocks? Is the sequence
important? If so, I agree George that it is the only way to write such a
complex schema. If the sequence is not so important, I suggest you use

<xs:element name="X">
<xs:complexType>
<xs:sequence>
<xs:element ref="Z"/>
<xs:element ref="Y" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>

which puts Z before the Y block. You can also add attribute in the Z
element to identify the sequence of Z.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Mar 16 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.