by Eric van der Vlist is published by O'Reilly & Associates (ISBN: 0596004214)


Mixed Content Models with Order

You have seen that a pattern interleaved with a group is allowed to appear anywhere between the patterns of the group. This feature may be used with a text pattern to define ordered mixed-content models, in which the text nodes may appear anywhere but the order of the elements is fixed. These content models are quite unusual in XML. A use case might be a data-oriented vocabulary such as our library, in which optional text can be inserted to provide more user-friendly documentation:

<character id="Lucy">
 <name>Lucy</name> made her first apparition in a Peanuts strip on
 <born>1952-03-03</born>, and the least we can say about her is that she is
 <qualification>bossy, crabby and selfish</qualification>.
</character>

If you want to fix the order of the child elements, just embed a group pattern inside a mixed pattern:

<!--This schema is INVALID-->
<element name="character">
  <mixed>
   <attribute name="id"/>
   <group>
     <element name="name">
       <text/>
     </element>
     <element name="born">
       <text/>
     </element>
     <element name="qualification">
      <text/>
     </element>
    </group>
   </mixed>
  </element>

Per the definition of the mixed pattern, this is equivalent to:

#This schema is invalid
<element name="character">
 <interleave>
  <attribute name="id"/>
  <text/>
  <group>
   <element name="name">
     <text/>
   </element>
   <element name="born">
     <text/>
   </element>
   <element name="qualification">
    <text/>
   </element>
  </group>
 </interleave>
</element>

The text pattern matches text nodes before, after, or between the elements of the group, but as you've seen with the previous museum example, the order of the elements in the group will still be enforced. The compact syntax uses the mixed pattern with commas between subpatterns to express this:

element character {
    mixed {
     attribute id {text},
     element name {text},
     element born {text},
     element qualification {text}
    }
   }

You have already seen that the compact syntax mixed pattern can be employed using ampersands and commas to define unordered and ordered mixed patterns. An "or" (|) can also interleave text nodes in choice patterns:

 element foo{
  mixed {
   (
    element in1.1 {empty},
    element in1.2 {empty}
   ) | (
    element in2.1 {empty}&
    element in2.2 {empty}
   )
  }
 }

This mixed pattern is interleaving text nodes into either a group (denoted by a comma) of in1.1 and in1.2 elements or (as shown by the pipe character) an interleave pattern (denoted by an ampersand) of elements in2.1 and in2.2. In the first case, because of the semantics of group patterns, the order between elements is fixed, while in the second case, the order doesn't matter. Mixed-choice contents don't constitute new content models. They are equivalent to choices of mixed-content models, and so, you can rewrite this schema as:

 element foo{
  (
   mixed{
    element in1.1 {empty},
    element in1.2 {empty}
    }
  ) | (
   mixed{
    element in2.1 {empty}&
    element in2.2 {empty}
   }
  )
 }
 }

This text is released under the Free Software Foundation GFDL.