XSD element substitution group example?
Asked Answered
H

1

11

I'd like to be able to specify single choice type for multiple extending types.

For example, say we have the sea, in the sea there are many kinds of fishes. So in XML I will write:

<Sea name="Atlantic Ocean">
 <Tuna name="tuna1" />
 <Carp name="carp1" />
 <Carp name="carp2" />
 <Tuna name="tuna2" />
 <Salmon name="salmon1" />
</Sea>

XSD

  <xs:complexType name="Fish">
  </xs:complexType>

  <xs:complexType name="Salmon">
    <xs:complexContent>
      <xs:extension base="Fish">
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Carp">
    <xs:complexContent>
      <xs:extension base="Fish">
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Tuna">
    <xs:complexContent>
      <xs:extension base="Fish">
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

  <xs:complexType name="Sea">
    <xs:complexContent>
      <xs:extension base="GeoZone">
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
          <xs:choice>
            <xs:element type="Fish" name="Fish" minOccurs="0" 
                        maxOccurs="unbounded"/>
          </xs:choice>
        </xs:sequence>
        <xs:attribute name="Name" type="xs:string" use="optional" />
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>

Unfortunately, that is not valid, as I can only add the type Fish itself and not its extending types.

Hymie answered 5/10, 2016 at 8:17 Comment(0)
M
19

Use an element substitution group...

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Sea">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="FishSubGroup"
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>

  <xs:element name="FishSubGroup" abstract="true"/>

  <xs:element name="Tuna" type="FishType" substitutionGroup="FishSubGroup"/>
  <xs:element name="Carp" type="FishType" substitutionGroup="FishSubGroup"/>
  <xs:element name="Salmon" type="FishType" substitutionGroup="FishSubGroup"/>

  <xs:complexType name="FishType">
    <xs:attribute name="name" type="xs:string"/>
  </xs:complexType>
</xs:schema>

XML

<?xml version="1.0" encoding="UTF-8"?>
<Sea name="Atlantic Ocean">
  <Tuna name="tuna1"/>
  <Carp name="carp1"/>
  <Carp name="carp2"/>
  <Tuna name="tuna2"/>
  <Salmon name="salmon1"/>
</Sea>
Midterm answered 5/10, 2016 at 23:24 Comment(1)
Wouldn't it be even better to declare the FishType at the abstract FishSubGroup element and only declare types on the substitution group elements, if they extend the FishType (none in this example)? See section 3.3.2 of the XML Schema specification: An <element> with no referenced or included type definition will correspond to an element declaration which has the same type definition as the first substitution-group head named in the substitutionGroup [attribute], if present, otherwise xs:anyType.Dissatisfied

© 2022 - 2024 — McMap. All rights reserved.