XSD Complex Elements

Building sophisticated XML structures with complex types

🏗️ XSD Complex Elements

Complex elements contain child elements, attributes, or both. They enable you to create hierarchical XML structures that model real-world data relationships effectively.


<!-- Complex element with children -->
<xs:element name="person">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="age" type="xs:integer"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>
                                    

Complex Type Indicators

Complex types use indicators to control how child elements are organized. These indicators define element order, choices, and grouping within complex structures.

📊

Sequence

Elements in specific order

<xs:sequence>
  <xs:element name="first"/>
  <xs:element name="second"/>
</xs:sequence>
🔀

Choice

One element from options

<xs:choice>
  <xs:element name="email"/>
  <xs:element name="phone"/>
</xs:choice>
🔄

All

Elements in any order

<xs:all>
  <xs:element name="name"/>
  <xs:element name="age"/>
</xs:all>
📦

Group

Reusable element groups

<xs:group name="addressGroup">
  <xs:sequence>...</xs:sequence>
</xs:group>

🔹 Sequence Indicator

The sequence indicator requires child elements to appear in a specific order.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="employee">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="firstName" type="xs:string"/>
        <xs:element name="lastName" type="xs:string"/>
        <xs:element name="department" type="xs:string"/>
        <xs:element name="salary" type="xs:decimal"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML (must be in order):

<employee>
  <firstName>John</firstName>
  <lastName>Smith</lastName>
  <department>IT</department>
  <salary>75000.00</salary>
</employee>

🔹 Choice Indicator

The choice indicator allows only one element from a set of options.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="contact">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <!-- Choose one contact method -->
        <xs:choice>
          <xs:element name="email" type="xs:string"/>
          <xs:element name="phone" type="xs:string"/>
          <xs:element name="fax" type="xs:string"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML (only one choice):

<contact>
  <name>Jane Doe</name>
  <email>[email protected]</email>
</contact>

<!-- OR -->

<contact>
  <name>John Smith</name>
  <phone>555-1234</phone>
</contact>

🔹 All Indicator

The all indicator allows elements to appear in any order, but each can appear only once.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="person">
    <xs:complexType>
      <xs:all>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="age" type="xs:integer"/>
        <xs:element name="country" type="xs:string"/>
      </xs:all>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML (any order):

<person>
  <country>USA</country>
  <name>Alice</name>
  <age>28</age>
</person>

<!-- Also valid -->

<person>
  <age>35</age>
  <country>Canada</country>
  <name>Bob</name>
</person>

🔹 Complex Type with Attributes

Combine child elements with attributes in complex types.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="book">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="title" type="xs:string"/>
        <xs:element name="author" type="xs:string"/>
        <xs:element name="publisher" type="xs:string"/>
      </xs:sequence>
      <!-- Attributes -->
      <xs:attribute name="isbn" type="xs:string" use="required"/>
      <xs:attribute name="year" type="xs:integer"/>
      <xs:attribute name="language" type="xs:string" default="English"/>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML:

<book isbn="978-0-123456-78-9" year="2024" language="English">
  <title>Learning XSD</title>
  <author>John Developer</author>
  <publisher>Tech Books Inc</publisher>
</book>

🔹 Empty Complex Elements

Complex elements with only attributes and no content.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="product">
    <xs:complexType>
      <xs:attribute name="id" type="xs:integer" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="price" type="xs:decimal" use="required"/>
      <xs:attribute name="inStock" type="xs:boolean" default="true"/>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML:

<product id="101" name="Laptop" price="999.99" inStock="true"/>

🔹 Mixed Content Complex Type

Allow both text and child elements within a complex element.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <xs:element name="description">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:element name="bold" type="xs:string" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="italic" type="xs:string" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="link" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="href" type="xs:anyURI"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML:

<description>
  This is <bold>important</bold> text with 
  <italic>emphasis</italic> and a 
  <link href="http://example.com">link</link>.
</description>

🔹 Named Complex Types (Reusable)

Define complex types once and reuse them across multiple elements.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <!-- Define reusable address type -->
  <xs:complexType name="addressType">
    <xs:sequence>
      <xs:element name="street" type="xs:string"/>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="state" type="xs:string"/>
      <xs:element name="zip" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
  
  <!-- Use the type in multiple elements -->
  <xs:element name="customer">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="name" type="xs:string"/>
        <xs:element name="billingAddress" type="addressType"/>
        <xs:element name="shippingAddress" type="addressType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  
</xs:schema>

Valid XML:

<customer>
  <name>John Doe</name>
  <billingAddress>
    <street>123 Main St</street>
    <city>New York</city>
    <state>NY</state>
    <zip>10001</zip>
  </billingAddress>
  <shippingAddress>
    <street>456 Oak Ave</street>
    <city>Boston</city>
    <state>MA</state>
    <zip>02101</zip>
  </shippingAddress>
</customer>

🔹 Extension and Restriction

Extend or restrict existing complex types to create new types.

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <!-- Base type -->
  <xs:complexType name="personType">
    <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="age" type="xs:integer"/>
    </xs:sequence>
  </xs:complexType>
  
  <!-- Extended type adds more elements -->
  <xs:complexType name="employeeType">
    <xs:complexContent>
      <xs:extension base="personType">
        <xs:sequence>
          <xs:element name="employeeId" type="xs:integer"/>
          <xs:element name="department" type="xs:string"/>
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  
  <xs:element name="employee" type="employeeType"/>
  
</xs:schema>

Valid XML:

<employee>
  <name>Alice Johnson</name>
  <age>32</age>
  <employeeId>12345</employeeId>
  <department>Engineering</department>
</employee>

🔹 Complex Element Best Practices

Follow these guidelines when designing complex elements.

✅ Best Practices:

  • Use named types: Define reusable complex types for consistency
  • Choose right indicator: Use sequence for order, choice for options, all for flexibility
  • Keep it simple: Avoid overly nested structures when possible
  • Document structure: Add annotations explaining complex hierarchies
  • Use extension wisely: Extend base types for related structures
  • Consider maintenance: Design for future changes and additions
  • Test thoroughly: Validate with various XML document structures

🧠 Test Your Knowledge

Which indicator allows elements to appear in any order?