Jump to content

Allowing specific permutations of attributes/elements

Recommended Posts

Sorry about the title...I couldn't figure out anything coherent to title the topic. Anyway, I'm new fish to Schema and I'm attempting to build a validator for XML relating to public transit.There is a root <segment> element which may contain exactly one or two of the following: <point/>, <pointStart/>, <pointEnd/>. Further, there can be at most one start, and at most one end. Since I come from a Perl background, consider the following regexp that has P standing in for <point/>, S for <pointStart/>, and E for <pointEnd/>:


Or, to appease certain engines that consider this nondeterministic,


The idea being that there must be one or two of them and, if two, they cannot be the same unless they are both plain <point/>s.Here is a schema that I've tested by brute force (using xmllint) to work in all cases:

<?xml version="1.0" ?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">	<xs:element name="segment">		<xs:complexType>			<xs:choice>				<xs:sequence>					<xs:element name="point"/>					<xs:choice minOccurs="0">						<xs:element name="point"/>						<xs:element name="pointStart"/>						<xs:element name="pointEnd"/>					</xs:choice>				</xs:sequence>				<xs:sequence>					<xs:element name="pointStart"/>					<xs:choice minOccurs="0">						<xs:element name="point"/>						<xs:element name="pointEnd"/>					</xs:choice>				</xs:sequence>				<xs:sequence>					<xs:element name="pointEnd"/>					<xs:choice minOccurs="0">						<xs:element name="point"/>						<xs:element name="pointStart"/>					</xs:choice>				</xs:sequence>			</xs:choice>		</xs:complexType>	</xs:element></xs:schema>

First question: Do I really have to spell it out the way I have, or is there a simpler equivalent? The idea of removing unnecessary ordering using <xs:all/> is tantalizing, but I can't think of a way to make it work.Second question: If I wanted to replace <pointStart/> and <pointEnd/> with <point type="start"/> and <point type="end"/>, respectively, would it be possible, and how would I go about it if so? (This question is the genesis of this post. It seems messy to have to move something that's obviously an attribute into the name just to make validation possible...)Thoughts?

Link to post
Share on other sites

So, in the whole document there can be only one Start, and ony one End, right?Well, then, you can have <point type="start"/> and <point type="end"/> if you label the type attribute as of type xs:ID. However, be warned that this would mean a "start" could appear after the "end". If that's no problem, then you could do:

<?xml version="1.0"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">	<xs:element name="segment">		<xs:complexType>			<xs:sequence>				<xs:element name="point" maxOccurs="unbounded">					<xs:complexType>						<xs:attribute name="type">							<xs:simpleType>								<xs:restriction base="xs:ID">									<xs:enumeration value="start"/>									<xs:enumeration value="end"/>									<xs:pattern value=".+"/>								</xs:restriction>							</xs:simpleType>						</xs:attribute>					</xs:complexType>				</xs:element>			</xs:sequence>		</xs:complexType>	</xs:element></xs:schema>

Also note that with the line

<xs:pattern value=".+"/>

I'm allowing other points to have IDs too. Remove that line if you want to leave other points IDless.Last, but certainly not least important, beware that a "start" and "end" may not appear at all. Just having

<segment>	<point/></segment>


<segment>	<point/>	<point/></segment>

would be legal.

Link to post
Share on other sites
So, in the whole document there can be only one Start, and ony one End, right?
Unfortunately, that's not the case...a subsequent version of the schema will allow multiple <segment/> elements, each potentially with its own start and end.It doesn't matter if start and end appear out of order as long as they are marked; order only matters if both points are unmarked, in which case the first is assumed the start.Thanks
Link to post
Share on other sites

In that case, I'm afraid the combination you've used at first is best. There's no way to make IDs unique only per region.Of course, you can always drop the marks, and as you say, treat the first one as a start, and the last one as an end.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...