Forum Moderators: open

Message Too Old, No Replies

XML Schema: Unsequenced After Sequenced

I want a preamble, followed by unordered data

         

cmarshall

2:37 pm on Feb 1, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I'll be investigating how to do this myself, but it would be timesaving if someone already has the answer.

Basically, what I want is the ability to specify a schema for this type of XML:


<container>
<preamble></preamble>
<someDataType1></someDataType1>
<someDataType2></someDataType2>
<someDataType1></someDataType1>
<someDataType3></someDataType3>
</container>

The idea is that the header will always be the first item, followed by an unordered list of subsequent items.

The problem comes when I try to specify that the preamble comes first, but anything goes after that.

<xs:all> [w3schools.com] allows arbitrary order. The problem is that I want to insist that the

<preamble>
element must always be first.

I can do it by enclosing the subsequent data in another container, but I'd like to try to avoid that if I can.

It does not look like you can have both an <xs:all> [w3schools.com] and an <xs:sequence> [w3schools.com] in the same <xs:complexType> [w3schools.com] element.

This is what I'd like to see:


<xs:element name="container">
<xs:complexType>
<xs:sequence>
<xs:element name="preamble"></xs:element>
<xs:all>
<xs:element name="someDataType1"></xs:element>
<xs:element name="someDataType2"></xs:element>
<xs:element name="someDataType3"></xs:element>
</xs:all>
</xs:sequence>
</xs:complexType>
</xs:element>

I hope that makes it clear. For the record, the schema above does not work. It is merely a way of specifying a concept.

cmarshall

6:47 pm on Feb 1, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Okay, further investigating...

This will work:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="header">
<xs:sequence>
<xs:element name="preamble"> </xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="data">
<xs:all>
<xs:element name="data_item1"> </xs:element>
<xs:element name="data_item2"> </xs:element>
<xs:element name="data_item3"> </xs:element>
</xs:all>
</xs:complexType>
<xs:element name="AutoBuildReadMe">
<xs:complexType>
<xs:sequence>
<xs:element name="head" type="header"/>
<xs:element name="body" type="data"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

However, this is NOT what I want. I don't want a "head" and a "body" section. I want to have their contents without the envelopes.

cmarshall

7:39 pm on Feb 1, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



This won't work:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:group name="datagroup">
<xs:all>
<xs:element name="data_item1"/>
<xs:element name="data_item2"/>
<xs:element name="data_item3"/>
</xs:all>
</xs:group>

<xs:element name="AutoBuildReadMe">
<xs:complexType>
<xs:sequence>
<xs:element name="preamble"/>
<xs:group ref="datagroup"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

However, THIS will:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:group name="datagroup">
<xs:sequence> <!-- We use xs:sequence here, instead of xs:all -->
<xs:element name="data_item1"/>
<xs:element name="data_item2"/>
<xs:element name="data_item3"/>
</xs:sequence>
</xs:group>

<xs:element name="AutoBuildReadMe">
<xs:complexType>
<xs:sequence>
<xs:element name="preamble"/>
<xs:group ref="datagroup"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

I need to be able to allow the following fields to be randomly-ordered.

cmarshall

2:48 pm on Feb 4, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



One of my employees applied some non-linear thinking, and came up with the solution:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="preamble"/>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element name="data1"/>
<xs:element name="data2"/>
<xs:element name="data3"/>
</xs:choice>
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

The way this works is that the

<xs:choice/>
element turns the
<xs:sequence/>
element into a de facto
<xs:all/>
element.