AlexG
AlexG

Reputation: 1103

XML (XSD) How-To: Element content is the name of another element

I'm trying to figure out how to write my XSD schema in order to express an element reference correctly. Here's a short example that explains what I'm trying to achieve. I have a few basic elements that all have different (unique) names. I would like to group them inside a bigger element by referencing them by name.

XML file:

<?xml version="1.0" encoding="UTF-8"?>
<RootNode>
  <BasicElements>
    <BasicElement name="Element1"/>
    <BasicElement name="Element2"/>
    <BasicElement name="Element3"/>
  <BasicElements>

  <ElementGroups>
    <ElementGroup name="ElementsAlongAPath">
      <LeftSide>Element1</LeftSide>
      <RightSide>Element2></RightSide>
    </ElementGroup>
    <ElementGroup name=OtherElementsAlongAPath">
      <LeftSide>Element2</LeftSide>
      <RightSide>Element3</RightSide>
    </ElementGroup>
  </ElementGroups>
</RootNode>

XSD file

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="TestNS" xmlns:test="TestNS">
  <xs:element name="RootNode">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="test:BasicElements" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="test:ElementGroups" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="BasicElements">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="test:BasicElement" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="BasicElement">
    <!--Attributes, stuff... -->
  </xs:element>
  <xs:element name="ElementGroups">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="test:ElementGroup" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="ElementGroup">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="LeftSide" minOccurs="0" maxOccurs="1">
          <!-- How to express reference to BasicElement here ?-->
        </xs:element>
        <xs:element name="RightSide" minOccurs="0" maxOccurs="1">
          <!-- How to express reference to BasicElement here ?-->
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

I could very well write that LeftSide and RightSide subelements are of type=xs:string and just write the name of the BasicElements I had above, but I was wondering how to do it in a way that is compliant with the XSD syntax. Thanks!

Upvotes: 0

Views: 545

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

This is what key and keyref are for. At the level of RootNode, define a key to make every .//BasicElement have a distinct @name, and a keyref to say that every .//LeftSide and .//Rightside must be a reference to one of these keys.

Upvotes: 1

Related Questions