Reputation: 1021
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 group
s, 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
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
<?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