Stewart Alan
Stewart Alan

Reputation: 1643

Adding a sequence of elements of the same type as the parent in an XSD

I am trying to create an XSD that validates the following XML structure

<SystemData>
  <Item Value="Techno" ListType="Flat">
    <Node Value="Detroit" />
    <Node Value="Gabba" />
  </Item>
  <Item Value="House" ListType="Tree">
    <Node Value="Deep">
       <Node Value="New York" />
    </Node>
    <Node Value="Acid" />
    <Node Value="Chicago" />
  </Item>
</SystemData>

Basically there is a root SystemData elements that contains a sequence of Item elements that can contain a sequence of Node elements, each of which can contain a sequence of node elements, modelling a tree like structure to n levels

So I have come up with this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="SystemData">
    <xs:complexType>
        <xs:sequence minOccurs="0" maxOccurs="unbounded">
            <xs:element name="Item">
                <xs:complexType>
                    <xs:sequence minOccurs="0" maxOccurs="unbounded">
                        <xs:element name="Node">
                            <xs:complexType>
                                <xs:attribute name="Value" type="xs:string" use="required"/>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                    <xs:attribute name="Value" type="xs:string" use="required"/>
                    <xs:attribute name="ListType" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:element>
</xs:schema>

How can I include the Node element as a sequence of itself?

Upvotes: 0

Views: 575

Answers (1)

Petru Gardea
Petru Gardea

Reputation: 21658

The idea is to make the content model referenceable, either by reusing a type within a type, or an element definition within an element definition. This hints to considering another criteria in choosing the approach, based on the authoring style.

Option 1: Reusing a type within a type, which is recommended with the Venetian blind authoring style.

I would change:

<xs:sequence minOccurs="0" maxOccurs="unbounded"> 
    <xs:element name="Node">
        <xs:complexType>
            <xs:attribute name="Value" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element> 
</xs:sequence>

To:

<xs:sequence>
    <xs:element name="Node" type="NodeType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>

And add:

<xs:complexType name="NodeType">
    <xs:sequence>
        <xs:element name="Node" type="NodeType" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:attribute name="Value" type="xs:string" use="required"/>
</xs:complexType>

Option 2: For a "Salami Slice" authoring style, you would need to reference a global element instead. So, I would change:

<xs:sequence minOccurs="0" maxOccurs="unbounded"> 
    <xs:element name="Node">
        <xs:complexType>
            <xs:attribute name="Value" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element> 
</xs:sequence>

To:

<xs:sequence>
    <xs:element ref="Node" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>

And add:

<xs:element name="Node">
    <xs:complexType>
        <xs:sequence>
        <xs:element ref="Node" minOccurs="0" maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute name="Value" type="xs:string" use="required"/>
    </xs:complexType>
</xs:element>

Upvotes: 1

Related Questions