Eric H.
Eric H.

Reputation: 2242

How to use extension to insert before an xsd:sequence?

In all examples about extending a sequence, all new elements are appened at the end. See personinfo and fullpersoninfo at : http://www.w3schools.com/schema/schema_complex.asp

How to define a new sequence by extension to insert new elements before ? Example (the 2nd part is wrong; how to correct it ?) :

<xs:complexType name="address">
  <xs:sequence>
    <xs:element name="city" type="xs:string"/>
    <xs:element name="country" type="xs:string"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="fullpersoninfo">
  <xs:complexContent>
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
    </xs:sequence>
    <xs:extension base="address"/>
  </xs:complexContent>
</xs:complexType>

The aim is to validate some elements where city and country are at the end of many sequences.

Example :

<Employee>
  <name>A.Miller</name>
  <city>Madrid</city>
  <country>Spain</country>
</Employee>
<Flight>
  <airport>CDG</airport>
  <city>Paris</city>
  <country>France</country>
</Flight>

Upvotes: 7

Views: 3679

Answers (1)

kjhughes
kjhughes

Reputation: 111686

As @Xstian mentioned in the comments, xs:extension doesn't work that way. Details follow, along with an alternative suggestion...

XSD 1.0

Extension cannot insert new elements before a sequence; they must be appended after the sequence. According to the XSD 1.0 spec, XML Schema Part 1: Structures Second Edition:

A complex type which extends another does so by having additional content model particles at the end of the other definition's content model, or by having additional attribute declarations, or both.

  • Note: This specification allows only appending, and not other kinds of extensions. This decision simplifies application processing required to cast instances from derived to base type. Future versions may allow more kinds of extension, requiring more complex transformations to effect casting.

XSD 1.1

Some special cases are supported but still not ones that would allow insertions before a sequence as you seek. According to the XSD 1.1 spec, W3C XML Schema Definition Language (XSD) 1.1 Part 1: Structures:

A complex type which extends another does so by having additional content model particles at the end of the other definition's content model, or by having additional attribute declarations, or both.

  • Note: For the most part, this specification allows only appending, and not other kinds of extensions. This decision simplifies application processing required to cast instances from the derived type to the base type. One special case allows the extension of all-groups in ways that do not guarantee that the new material occurs only at the end of the content. Another special case is extension via Open Contents in interleave mode.

Alternative Suggestion: Groups

Instead of xs:extension you could use xs:group to factor out the common element definitions and insert new elements before them.

XML

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <Employee>
    <name>A.Miller</name>
    <city>Madrid</city>
    <country>Spain</country>
  </Employee>
  <Flight>
    <airport>CDG</airport>
    <city>Paris</city>
    <country>France</country>
  </Flight>
</root>

XSD

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

  <xs:group name="AddressGroup">
    <xs:sequence>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
    </xs:sequence>
  </xs:group>

  <xs:complexType name="EmployeeType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:group ref="AddressGroup"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="FlightType">
    <xs:sequence>
      <xs:element name="airport" type="xs:string"/>
      <xs:group ref="AddressGroup"/>
    </xs:sequence>
  </xs:complexType>

  <xs:element name="root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Employee" type="EmployeeType"/>
        <xs:element name="Flight" type="FlightType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

Upvotes: 10

Related Questions