mmutilva
mmutilva

Reputation: 18994

Specify sorting in lists of elements in XML Schema

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

Answers (2)

Michael Kay
Michael Kay

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:

  1. 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

  2. I've used the negative form not(a le b) deliberately because it's true for all elements even the first

  3. 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

C. M. Sperberg-McQueen
C. M. Sperberg-McQueen

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

Related Questions