Is it possible in W3C's XML Schema language (XSD) to allow a series of elements to be in any order but still limit occurrences?

StackOverflow https://stackoverflow.com/questions/104248

  •  01-07-2019
  •  | 
  •  

Question

I know about all and choice, but they don't account for a case where I do want some elements to be able to occur more than once, such as:

<Root>
    <ThingA/>
    <ThingB/>
    <ThingC/>
    <ThingC/>
    <ThingC/>
</Root>

I could use sequence, but I'd prefer to allow these children to be in any order. I could use any, but then I couldn't have more than one ThingC. I could use choice, but then I couldn't limit ThingA and ThingB to 0 or 1.

I think I may have read somewhere that this was either difficult or impossible in XSD, but might be possible with RELAX NG. I don't remember where I read that, unfortunately.

Thanks for any help!

Was it helpful?

Solution

That's right: you can't do what you want to do in XML Schema, but you can in RELAX NG with:

<element name="Root">
  <interleave>
    <element name="ThingA"><empty /></element>
    <element name="ThingB"><empty /></element>
    <oneOrMore><element name="ThingC"><empty /></element></oneOrMore>
  </interleave>
</element>

Your options in XML Schema are:

  • add a preprocessing step that normalises your input XML into a particular order, and then use <xs:sequence>
  • use <xs:choice>, and add extra validation (for example using Schematron) to check that there's not more than one <ThingA> or <ThingB>
  • decide to fix the order of the elements in your markup language

It turns out that the third is usually the best option; there's usually not much cost for generators of XML to output elements in a particular order, and not only does it help validation but it also aids consumption of the XML if the order can be known in advance.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top