Reputation: 18994
Is there a way to specify in an XML Schema that the elements of a list must appear sorted by some text nodes?
E.g.:
I want to craft an xsd for which the following xml is valid:
<root>
<Users>
<User>
<Id>1</Id>
<Username>lsuarez</Username>
</User>
<User>
<Id>3</Id>
<Username>dforlan</Username>
</User>
<User>
<Id>7</Id>
<Username>ecavanni</Username>
</User>
</Users>
</root>
But the following is not:
<root>
<Users>
<User>
<Id>7</Id>
<Username>ecavanni</Username>
</User>
<User>
<Id>1</Id>
<Username>lsuarez</Username>
</User>
<User>
<Id>3</Id>
<Username>dforlan</Username>
</User>
</Users>
</root>
That is, the elements in the collection appear sorted by User.Id
Upvotes: 2
Views: 967
Reputation: 163322
Adding to MS-McQ's answer: specifically in XSD 1.1, you need an assertion on the complex type of the Users element, of the form
test="every $u in User satisfies not($u/Id le $u/preceding-sibling::User[1]/Id)"
Notes:
The assertion can't be on an individual User element because it's an assertion about the subtree rooted at the element on which the assertion appears, and has no access to data outside that subtree
I've used the negative form not(a le b) deliberately because it's true for all elements even the first
If you use Saxon as your XSD 1.1 processor, assertions of the form "every User satisfies c" are optimized in the sense that if the assertion fails, the error message will tell you which particular User failed to satisfy the condition.
Upvotes: 5
Reputation: 25034
In XSD 1.1, you could use an assertion on the type used for Users (or root) to enforce this. I can't think of a way to do it in XSD 1.0 (but perhaps some other ingenious SO reader can).
Upvotes: 0