Reputation: 129
I have two tags which resemble some kind of boolean expression:
<complexType name="condition">
<choice minOccurs="0">
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
</choice>
</complexType>
<complexType name="condition-a">
<all>
<element name="value" type="string"/>
</all>
</complexType>
<complexType name="condition-b">
<all>
<element name="value" type="string"/>
</all>
</complexType>
I would like to combine these conditions with and
, or
and not
constructions. Like this:
<condition>
<and>
<condition-a><value>X</value></condition-a>
<condition-b><value>Y</value></condition-b>
<not>
<condition-a><value>Z</value></condition-a>
</not>
</and>
</condition>
Note that the condition
tag is only used at the top, not inside and
, or
and not
.
I came up with the following definitions:
<complexType name="condition">
<choice minOccurs="0">
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
<element name="and" type="myns:condition-and"/>
<element name="or" type="myns:condition-or"/>
<element name="not" type="myns:condition-not"/>
</choice>
</complexType>
<complexType name="condition-a">
<all>
<element name="value" type="string"/>
</all>
</complexType>
<complexType name="condition-b">
<all>
<element name="value" type="string"/>
</all>
</complexType>
<complexType name="condition-and">
<choice maxOccurs="unbounded">
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
<element name="and" type="myns:condition-and"/>
<element name="or" type="myns:condition-or"/>
<element name="not" type="myns:condition-not"/>
</choice>
</complexType>
<complexType name="condition-or">
<choice maxOccurs="unbounded">
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
<element name="and" type="myns:condition-and"/>
<element name="or" type="myns:condition-or"/>
<element name="not" type="myns:condition-not"/>
</choice>
</complexType>
<complexType name="condition-not">
<choice>
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
<element name="and" type="myns:condition-and"/>
<element name="or" type="myns:condition-or"/>
<element name="not" type="myns:condition-not"/>
</choice>
</complexType>
Although this works, it is not optimal. I am repeating the possible conditions in the and
, or
and not
tags. As a side effect, the generated JAXB code is a mess.
Is there a more elegant approach for this?
Upvotes: 2
Views: 48
Reputation: 6016
Instead of repeating the same choice multiple times XML Schema allows you to create a global xs:group (xs:choice, xs:sequence or xs:all) and reference it in other parts of your schema, just like global types and elements.
So you can use something like this:
<group name="anyCondition">
<choice>
<element name="a" type="myns:condition-a"/>
<element name="b" type="myns:condition-b"/>
<element name="and" type="myns:condition-and"/>
<element name="or" type="myns:condition-or"/>
<element name="not" type="myns:condition-not"/>
</choice>
</group>
<complexType name="condition-and">
<group ref="myns:anyCondition" maxOccurs="unbounded"/>
</complexType>
<complexType name="condition-or">
<group ref="myns:anyCondition" maxOccurs="unbounded"/>
</complexType>
<complexType name="condition-not">
<group ref="myns:anyCondition"/>
</complexType>
Upvotes: 1