Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

xml

xsd

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>
like image 232
Eric H. Avatar asked Mar 18 '15 09:03

Eric H.


1 Answers

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>
like image 148
kjhughes Avatar answered Nov 27 '22 15:11

kjhughes