Steve Kelio
Steve Kelio

Reputation: 129

XSD - Re-use/inheritance of tags

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

Answers (1)

sergioFC
sergioFC

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

Related Questions