Home > Software engineering >  xsd: complex type with alternatives
xsd: complex type with alternatives

Time:10-22

I have the following xsd to define a number of fields with type text|select|password|checkbox and content being either empty or a list of field-options. Working all fine so far.

Now I want to allow field-options only for type text|select, for any other type <field> must be empty.

I already found alternatives, but simply don't know how to use/where to put them. I really am a xsd novice.

<fields>
    <field type="text" />
    <field type="select">
        <field-option>Option 1</field-option>
        <field-option>Option 2</field-option>
        <field-option>Option 3</field-option>
    </field>
    <field type="password" />
    <field type="checkbox" />
</fields>
<xs:element name="fields" minOccurs="0">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="field" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="field-option" type="xs:string" minOccurs="0" maxOccurs="unbounded" />
                    </xs:sequence>
                    <xs:attribute name="type" use="required">
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:pattern value="text|password|select|checkbox" />
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:attribute>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>

CodePudding user response:

Type alternatives require XSD 1.1, if you can use that (e.g. with XSD 1.1 version of Xerces or with Saxon EE) you can try

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">
  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="fields"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="fields">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" ref="field"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:complexType name="field-base-type">
    <xs:attribute name="type">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="text"/>
          <xs:enumeration value="password"/>
          <xs:enumeration value="select"/>
          <xs:enumeration value="checkbox"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>
  </xs:complexType>
  <xs:element name="field">
    <xs:alternative test="@type = ('checkbox', 'password')" type="field-base-type"/>
    <xs:alternative test="@type = ('select', 'text')">
      <xs:complexType>
        <xs:complexContent>
          <xs:extension base="field-base-type">
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" ref="field-option"/>
            </xs:sequence>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>
    </xs:alternative>
  </xs:element>
  <xs:element name="field-option" type="xs:string"/>
</xs:schema>

The first fields below is then valid, the second not, its field type="checkbox" element is flagged as invalid:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="sample2.xsd">
    <fields>
        <field type="text" />
        <field type="select">
            <field-option>Option 1</field-option>
            <field-option>Option 2</field-option>
            <field-option>Option 3</field-option>
        </field>
        <field type="password" />
        <field type="checkbox" />
    </fields> 
    <fields>
        <field type="text" />
        <field type="checkbox">
            <field-option>Option 1</field-option>
            <field-option>Option 2</field-option>
            <field-option>Option 3</field-option>
        </field>
        <field type="password" />
        <field type="select" />
    </fields>
</root>
  • Related