1

I am not sure what would be a good XML structure for the following...

Assume that a field type, say <person>, can have different "flavors", e.g. either the person is a local reference defined only by some ID, or it is a global reference with various address elements associated. What would be a good XML structure for this so that it becomes easy to describe in a schema (an xsd file)?

I see two strategies - bot both with some major drawbacks:

Either the person type is defied as a separate element, say <type>, but then I guess a schema cannot tell which of the type specific fields that are mandatory:

<person>
   <type>local</type>
   <id>12345</id>
</person>
<person>
   <type>global</type>
   <name>Some Name</name>
   <address>Some Street 42</address>
   <city>Some City</some>
</person>

In this case <id> should only be mandatory for "local" person types, and similarly with the fields for "global" person types.

The other strategy is to define a new node type for each person sub-type, but then we cannot tell that each sub-type is in fact just a flavor of <person>:

<personLocal>
   <id>12345</id>
</personLocal>
<personGlobal>
   <name>Some Name</name>
   <address>Some Street 42</address>
   <city>Some City</some>
</personGlobal>

What is a good strategy for modeling structures like this?

someName
  • 1,275
  • 2
  • 14
  • 33

3 Answers3

1

You can use the following (partial) schema:

    <xs:element name="person">
      <xs:complexType>
        <xs:choice>
          <xs:element name="id" type ="xs:int"/>
          <xs:sequence>
            <xs:element name="name" type="xs:string" />
            <xs:element name="address" type="xs:string" />
            <xs:element name="city" type="xs:string" />
          </xs:sequence>
        </xs:choice>
      </xs:complexType>
    </xs:element>

Important: The xs:choice tag.

This will result in the following:

  • When the first tag inside the person tag is the id tag, no other tags are allowed.
  • When the first tag inside the person tag is the name tag, the address and city tags are mandatory, the id tag is not allowed.
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443
  • Aah, that looks good! Would you then just put the "type" identifier (i.e. global/local) in an xs:element for each choice? That is, the "local" person choice would require an element, "type" with required value "local". Or how would you do this? – someName Mar 29 '11 at 09:41
  • I didn't include this in the schema, because it is already unambiguous. Including the type would make the schema more complex, because dependent on the value of the type attribute (yes, it should be an attribute, not a tag on its own), different rules would apply. – Daniel Hilgarth Mar 29 '11 at 09:43
  • Update: According to [this question](http://stackoverflow.com/questions/2813823/xsd-different-sub-elements-depending-on-attribute-element-value) it is not just hard to do it, it is impossible... – Daniel Hilgarth Mar 29 '11 at 09:46
  • BTW: If my answer helped you, please be so kind and update and accept it – Daniel Hilgarth Mar 29 '11 at 09:48
  • Thanks! It fully answered my question. :-) – someName Mar 29 '11 at 11:25
0

For me, I do that like this :

<parent>
  <local>
    <person>
      <name />
      <adress />
      <city />
    </person>    
  </local>
  <global>
    <person>
      <name />
      <adress />
      <city />
    </person>    
  </global>
<parent>

Or like this :

<person type='local'>
  <name />
  <adress />
  <city />
</person>    
<person type='global'>
  <name />
  <adress />
  <city />
</person>

:)

Patrick Ferreira
  • 1,983
  • 1
  • 15
  • 31
  • I fail to see how any of the two examples allow a schema to specify that a "local" person should only contain an ID (and the ID is mandatory), and a "global" person should only contain the address elements (but not the ID). – someName Mar 29 '11 at 09:38
0

One workarround (the one that I probably ends up with) is to define the schema as below, because different person types (there are more than the two examples I explained) may contain some of the same fields:

<xs:element name="person">
<xs:complexType>
  <xs:choice>
    <xs:element name="local">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="id" type ="xs:int"/>
        </xs:sequence>
      </xs:complexType>
    </xs:element>
    <xs:element name="global">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="name" type="xs:string" />
          <xs:element name="address" type="xs:string" />
          <xs:element name="city" type="xs:string" />
        </xs:sequence>
      </xs:complexType>
    </xs:element>
  </xs:choice>
</xs:complexType>

someName
  • 1,275
  • 2
  • 14
  • 33