|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
XML Schema to describe specifc caseHi,
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 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 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 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 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 } XML syntax:| element Y3 { text })* } <?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 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." |
|||||||||||||||||||||||