ShapeOfMatter
ShapeOfMatter

Reputation: 1021

XSD all inside choice

I have the inverse need from this other question.

I'd like either of the following to be valid:

<a>
  <b></b>
  <c></c>
</a>
<a>
  <d></d>
  <e></e>
</a>

I tried doing a choice with two all children, but that's invalid.
It looks like I could do a choice with two sequence children, but I don't want implementers to have to worry about the order of elements.
It also looks like I could use groups, but they require ref names, and the options for the contents don't have obvious names for their groupings. (If they did I'd have structured the XML that way to begin with.)

I've been working off of the XSD 1.1 documentation.

I'm trying to have my XSD generated from a data structure (Mostly so I can recycle the annotations etc for documentation), so simplicity is important.

Upvotes: 0

Views: 209

Answers (1)

Sprotty
Sprotty

Reputation: 6003

While this is technically possible in XSD 1.1, the solution is not very nice...

The solution I've got sticks everything in an xs:all, then uses an xs:assert (XSD 1.1 only) to provide the rules.

This solution while it does work is difficult to read and maintain, and not compatible with XSD 1.0. I would lean towards the choice(seq(b,c), seq(d,e)) solution you described and put the onus on the implementers to get the order right

XSD represented graphically using Liquid XML Studio

<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2019 BETA (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="a">
        <xs:complexType>
            <xs:all>
                <xs:element name="b" minOccurs="0" />
                <xs:element name="c" minOccurs="0" />
                <xs:element name="d" minOccurs="0" />
                <xs:element name="e" minOccurs="0" />
            </xs:all>
            <xs:assert test="((boolean(b) and boolean(c)) or (boolean(d) and boolean(e))) and not ((boolean(b) and boolean(c)) and (boolean(d) and boolean(e)))" />
        </xs:complexType>
    </xs:element>
</xs:schema>

Upvotes: 1

Related Questions