SergeZ
SergeZ

Reputation: 408

XSD nested element recursion

I am completely new to XSD so, my question may looks like the obvious one, but, anyway...

Consider I have the following XML:

<om:model xmlns:om="http://www.r-style.com/2014/odm-model">
    <om:entry>
        <om:key>KEY1</om:key>
        <om:value>VALUE1</om:value>
    </om:entry>
    <om:entry>
        <om:key>KEY2</om:key>
        <om:value>VALUE2</om:value>
    </om:entry>
    <om:entry>
        <om:key>KEY3<om:key>
        <om:value>
            <om:model>
                <om:entry>
                    <om:key>KEY4</om:key>
                    <om:value>VALUE4</om:value>
                </om:entry>
                <om:entry>
                    <om:key>KEY5</om:key>
                    <om:value>VALU5E</om:value>
                </om:entry>
            </om:model>
        </om:value>
    </om:entry>
</om:model>

Is there a way to create such a XSD schema to specify that in tag it is allowed to set either real value ( of type String ) or nest a XML itself. As a result I would like to have either key-value pair or key-xml pair, and that xml should also contains stuff like either key-value pair or key-xml pair. Etc...

Thank you for your time!

P.S.: at the moment I've tried to use the following XSDSchema but still have to sure whether it is correct or now:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.r-style.com/2014/odm-model">
  <xs:element xmlns:odm="http://www.r-style.com/2014/odm-model" name="model" type="odm:modelType"/>
  <xs:complexType name="entryType">
    <xs:sequence>
      <xs:element type="xs:string" name="key"/>
      <xs:element name="value">
        <xs:complexType mixed="true">
          <xs:sequence>
            <xs:element xmlns:odm="http://www.r-style.com/2014/odm-model" type="odm:modelType" name="model" minOccurs="0"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="modelType">
    <xs:sequence>
      <xs:element xmlns:odm="http://www.r-style.com/2014/odm-model" type="odm:entryType" name="entry" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="valueType">
    <xs:sequence>
      <xs:element xmlns:odm="http://www.r-style.com/2014/odm-model" type="odm:modelType" name="model" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

Upvotes: 0

Views: 534

Answers (1)

potame
potame

Reputation: 7905

Your schema looks fine to me; it should work well for what you want to do.

As a precision, setting a content model like either text or some tags exclusively is not possible in XML. You need to use a mixed content model, and it always be possible to insert some text, even if an <om:model> is inserted.

To avoid this, you can wrap the textual content of the <om:value> in a tag, e.g. <om:str>, and use an <xs:choice> in the schema definition, yielding to something like that:

  <xs:element name="value">
    <xs:complexType>
      <xs:choice>
        <xs:element name="model"/>
        <xs:element name="str" type="xs:string" />
      </xs:choice>
    </xs:complexType>
  </xs:element>

Other possibility: with schema 1.1., you may be able to add an <xs:assert> condition within the <xs:complexType>.

Just one small remark: to avoid repetion of xmlns:odm="http://www.r-style.com/2014/odm-model" everywhere, just set the namespace declaration on the <xs:schema> root declaration:

<xs:schema xmlns:odm="http://www.r-style.com/2014/odm-model" 

Upvotes: 1

Related Questions