Joel Bodenmann
Joel Bodenmann

Reputation: 2282

XML schema for recursive key-value pairs

Consider the following XML sample document that holds variables with key-value pairs that can also be recursive:

<?xml version="1.0" encoding="UTF-8"?>
<environments>
    <variable>
        <key>Variable 1</key>
        <value>Value</value>
    </variable>

    <variable>
        <value>B</value>
        <key>Variable 2</key>
    </variable>

    <variable>
        <value></value>
        <key>Variable 2</key>
    </variable>

    <variable>
        <key>Variable 2</key>
        <value>
            <variable>
                <key>Foo</key>
                <value>Bar</value>
            </variable>
        </value>
    </variable>

    <variable>
        <key>Variable 2</key>
        <value>
            <variable>
                <key>Foo</key>
                <value>
                    <variable>
                        <key>Foo</key>
                        <value>Bar</value>
                    </variable>
                </value>
            </variable>
        </value>
    </variable>
</environments>

I'd like to create an XML schema that can verify this structure: Zero or more variable elements, key elements are string only and value elements are string only or nested variables.

So far I came up with this:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1">

  <!-- Element: Environments -->
  <xs:element name="environments">
    <xs:complexType>
      <xs:sequence maxOccurs="unbounded">
        <xs:element ref="variable"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <!-- Element: variable_type -->   
  <xs:element name="variable">
    <xs:complexType>

        <xs:all>
          <xs:element ref="key"/>
          <xs:element ref="value"/>
        </xs:all>

    </xs:complexType>
  </xs:element>

  <!-- Element: key -->
  <xs:element name="key" type="xs:string"/>

  <!-- Element: value -->
  <xs:element name="value">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:choice>
          <xs:element minOccurs="0" maxOccurs="unbounded" ref="variable"/>
        </xs:choice>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

This schema works for my sample document. However, I'm very unsure when it comes to the value element: <xs:complexType mixed="true">. This would mean that a variable element like this would be considered as valid as well (extra foo characters before the nested variable element):

    <variable>
        <key>Variable 2</key>
        <value>
            foo
            <variable>
                <key>Foo</key>
                <value>Bar</value>
            </variable>
        </value>
    </variable>

My question: How can I be sure that the value element is either another variable element (complex type) or just a string?

Upvotes: 0

Views: 628

Answers (1)

Michael Kay
Michael Kay

Reputation: 163322

Mixed content in XSD really only works for narrative text documents. There are very few effective constraints you can impose on mixed content except by using XSD 1.1 assertions. It's best to avoid this kind of content model if you can.

Upvotes: 1

Related Questions