Pattern Compositions

In the preceding example, we combined a choice pattern with a group pattern. This process can be expanded so that there is virtually no restriction or limit on the way compositors can be combined. As an example, let’s say we want our character element to allow either one name element or the three elements first-name, middle-name (optional), and last-name in any order, but require that they appear before the born and qualification elements. To do that, write:

<element name="character">
 <attribute name="id"/>
 <choice>
  <element name="name"><text/></element>
  <interleave>
   <element name="first-name"><text/></element>
   <optional>
    <element name="middle-name"><text/></element>
   </optional>
   <element name="last-name"><text/></element>
  </interleave>
 </choice>
 <element name="born"><text/></element>
 <element name="qualification"><text/></element>
</element>

or, with the compact syntax:

element character {
   attribute id { text },
   (element name { text }
    | (element first-name { text }
       & element middle-name { text }?
       & element last-name { text })),
   element born { text },
   element qualification { text }
}

Note that two levels of parentheses have been added. In the compact syntax, operators determine the nature of compositors (group, interleave, or choice). Operators can’t be mixed within one set of parentheses or curly brackets, so you need to use these parentheses to explicitly mark where each compositor begins and ends.

These schemas validate any of the following (and varied) character ...

Get RELAX NG now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.