Jump to content

Sequential Required and Unordered Optional Elements


echotrain

Recommended Posts

I am having trouble building a schema that will validate sequential required elements followed by randomly ordered optional elements. This XML snippet is an example:

<Record>	 <RequiredElementOne>Must be first</RequiredElementOne>	 <RequiredElementTwo>Must be second</RequiredElementTwo>	 <OptionalElementOne>0-unbounded in any order</OptionalElementOne>	 <OptionalElementTwo>0-unbounded in any order</OptionalElementTwo></Record>

Either of the OptionalElements may or may not be present, in any quantity, in any order, and they must follow the RequiredElements. I have been trying variations on this:

<xs:element name="Record">    <xs:complexType>	  <xs:sequence>	    <xs:element ref="RequiredElementOne" />	    <xs:element ref="RequiredElementTwo" />	    <xs:group ref="OptionalGroup" />	  </xs:sequence>    </xs:complexType></xs:element><xs:element name="RequiredOne" /><xs:element name="RequiredTwo" /><xs:group name="OptionalGroup">    <xs:all>	  <xs:element name="OptionalElementOne" />	  <xs:element name="OptionalElementTwo" />    </xs:all></xs:group>

I keep bumping into the fact that xs:sequence and xs:all seem to be mutually exclusive. Any thoughts would be appreciated.

Link to comment
Share on other sites

Yes, they are mutually exclusive, at least in XML Schema 1.0... you'd have to change your grammer so that you have just one optional element in a strict order, which may contain the rest in any order.Like:

<Record><RequiredElementOne>Must be first</RequiredElementOne><RequiredElementTwo>Must be second</RequiredElementTwo><OptionalElementHolder><OptionalElementOne>0-unbounded in any order</OptionalElementOne><OptionalElementTwo>0-unbounded in any order</OptionalElementTwo></OptionalElementHolder></Record>

and

<xs:element name="OptionalElementHolder" /><xs:group name="OptionalGroup"><xs:all><xs:element name="OptionalElementOne" /><xs:element name="OptionalElementTwo" /></xs:all></xs:group></xs:element>

Link to comment
Share on other sites

Thanks for your reply, boen_robot. I could live with that, but I couldn't get it to work. I could not get my parser to accept xs:all nested inside xs:group, however it did work nested in xs:complexType. So far, so good. But, now I find that the maxOccurs limit on elements within xs:all is 1. Since the minOccurs on my OptionalElements is 0 and the maxOccurs is unbounded, a Record element could have any number of ElementHolders that each hold only one element. As might be imagined, the production data structure is considerably more complex than these examples, and could easily become cluttered. I feel like this is on the right track. A little more brainstorming is needed.

Link to comment
Share on other sites

My editor seems to say otherwise... the following schema is verified to be valid:

	<xs:element name="Record">		<xs:complexType>			<xs:sequence>				<xs:element name="RequiredElementOne"/>				<xs:element name="RequiredElementTwo"/>				<xs:element name="OptionalElementHolder" minOccurs="0">					<xs:complexType>						<xs:all>							<xs:element name="OptionalElementOne" minOccurs="0" maxOccurs="unbounded"/>							<xs:element name="OptionalElementTwo" minOccurs="0" maxOccurs="unbounded"/>						</xs:all>					</xs:complexType>				</xs:element>			</xs:sequence>		</xs:complexType>	</xs:element>

(optional elements can occur zero or more times in any order, as long as they're within OptionalElementHolder, which itself exists once as the last Record child element, or is not present at all)

Link to comment
Share on other sites

I am using Visual Studio, and consequently the MSXML engine: 0, 1 or left blank is all it will accept. I did some searching on this and found these references: http://connect.microsoft.com/VisualStudio/feedback/details/122890/xsd-xml-editor-incorrectly-complains-about-maxoccurs-1-in-xs-all-compositor That page refers to W3.org: http://www.w3.org/TR/xmlschema-1/#declare-contentModel Stylus Studio makes the same complaint, and I found this on their site: http://www.stylusstudio.com/xmldev/200110/post90460.html Thanks very much for your help. I feel a solution is lurking out there. More brainstorming!

Link to comment
Share on other sites

I use Stylus Studio.... although I didn't tried to actually validate a document against it... just validated the schema itself, and there's no errors on that.

Link to comment
Share on other sites

OK, here is what I came up with. It's not pretty, but it validates. I'll try it out on the application Monday and report back.

 <xs:element name="Record">  <xs:complexType>   <xs:sequence>    <xs:element name="RequiredElementOne"/>    <xs:element name="RequiredElementTwo"/>    <xs:element name="Holder"  minOccurs="0">	 <xs:complexType>	  <xs:all>	   <xs:element name="OneHolder" minOccurs="0">	    <xs:complexType>		 <xs:sequence>		  <xs:element name="OptionalElementOne" minOccurs="0" maxOccurs="unbounded"/>		 </xs:sequence>	    </xs:complexType>	   </xs:element>	   <xs:element name="TwoHolder" minOccurs="0">	    <xs:complexType>		 <xs:sequence>		  <xs:element name="OptionalElementTwo" minOccurs="0" maxOccurs="unbounded"/>		 </xs:sequence>	    </xs:complexType>	   </xs:element>	  </xs:all>	 </xs:complexType>    </xs:element>   </xs:sequence>  </xs:complexType></xs:element>

Link to comment
Share on other sites

OK, I tried to generate an XML file using my XML Schema, and it failed indeed. But I was reminded of an alternative approach... xs:choice can have quantifiers. Setting it to 0-unbounded along with its elements being fixed results in what I described above - a single optional element holder in which optional elements can appear zero or more times in any order:

	<xs:element name="Record">		<xs:complexType>			<xs:sequence>				<xs:element name="RequiredElementOne"/>				<xs:element name="RequiredElementTwo"/>				<xs:element name="OptionalElementHolder" minOccurs="0">					<xs:complexType>						<xs:choice minOccurs="0" maxOccurs="unbounded">							<xs:element name="OptionalElementOne"/>							<xs:element name="OptionalElementTwo"/>						</xs:choice>					</xs:complexType>				</xs:element>			</xs:sequence>		</xs:complexType>	</xs:element>

Link to comment
Share on other sites

No. The choice itself (not its elements) can occur between 0 and unlimited number of times. Each time you do make a choice, it's a choice between one OptionalElementOne or one OptionalElementTwo.The following XML validates with all validators using Stylus Studio:

<?xml version="1.0"?><Record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="TEST.xsd">    <RequiredElementOne>string by default</RequiredElementOne>    <RequiredElementTwo>string by default</RequiredElementTwo>    <!--Element OptionalElementHolder is optional-->    <OptionalElementHolder>        <OptionalElementTwo>string by default</OptionalElementTwo>        <OptionalElementTwo>string by default</OptionalElementTwo>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementTwo>string by default</OptionalElementTwo>        <OptionalElementTwo>string by default</OptionalElementTwo>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementTwo>string by default</OptionalElementTwo>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementOne>string by default</OptionalElementOne>        <OptionalElementOne>string by default</OptionalElementOne>    </OptionalElementHolder></Record>

Link to comment
Share on other sites

I have run my application with the xs:choice structure, and it does the job! It's clearer to me now, having seeing it in action - it's like restricting an element to a string or an integer, but in the case of xs:choice, the type is one of the element definitions. Thanks for the ideas, boen_robot, especially the one that worked. :D

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...