!!!Getting started

Throughout the book, we will be using variations of the same document describing a library:

 <?xml version="1.0"?>
 <library>
  <book id="b0836217462" available="true">
   <isbn>0836217462</isbn>
   <title xml:lang="en">Being a Dog Is a Full-Time Job</title>
   <author id="CMS">
    <name>Charles M Schulz</name>
    <born>1922-11-26</born>
    <died>2000-02-12</died>
   </author>
   <character id="PP">
    <name>Peppermint Patty</name>
    <born>1966-08-22</born>
    <qualification>bold, brash and tomboyish</qualification>
    </character>
   <character id="Snoopy">
    <name>Snoopy</name>
    <born>1950-10-04</born>
    <qualification>extroverted beagle</qualification>
   </character>
   <character id="Schroeder">
    <name>Schroeder</name>
    <born>1951-05-30</born>
    <qualification>brought classical music to the Peanuts strip</qualification>
   </character>zeroOrMore
   <character id="Lucy">
    <name>Lucy</name>
    <born>1952-03-03</born>
    <qualification>bossy, crabby and selfish</qualification>
   </character>
  </book>
 </library>


!!!Our first patterns

In plain English, we could describe this document as being:
* a "library" element composed of one of more
** "book" elements having
*** "id" and "available" attributes and
*** an "isbn" element composed of text
*** a "title" element with a xml:lang attribute and a text node
*** one or more "author" elements with
**** an "id" attribute
**** a "name" element
**** an optional "born" element
**** an optional "died" element
*** zero or more "character" elements with
**** an "id" attribute
**** a "name" element
**** an optional "born" element
**** a "qualification" element.

The good news -and what makes Relax NG so easy to learn- is that in its simplest flavor,it's pretty much a XML formalization of this statement with simple matching rules:

* "library element" translates into <element name="library">...</element>
* "id attribute" translates into "<attribute name="id"/>
* "one or more" becomes: <oneOrMore>...</oneOrMore>
* "zero or more" becomes: <zeroOrMore>...</zeroOrMore>
* "text" is: <text/>
* "optional" is: <optional>...</optional>

We've seen in "Chapter 2: Simple Is Beautiful" that almost everything is a pattern for Relax NG and each of these Relax NG elements are patterns. Let's now spend some time to introduce each of them.

!!<text/>

This pattern is the simplest we can think of and simply matches a text node. More exactly, it matches zero or text nodes and we'll see in "Chapter 6: More Patterns" that the "text" it makes a difference in the context of mixed content models (i.e. to define elements which may have both sub elements and text nodes) but until then we can think of it as matching a text node.

By extension the "text" pattern also matches any attribute value even if attribute values are not considered as nodes by the XML infoset.

The XML expression for "text" patterns is just:

 <text/>

!!<attribute/>

As expected, the "attribute" pattern matches attributes. The name of these attributes are defined in the "name" attribute of the "attribute" pattern and the content of these attributes is defined as a child element of the "attribute" pattern (don't worry, that's easier to write and read than to explain!).

To define the "id" attribute, we could thus write:

 <attribute name="id">
  <text/>
 </attribute>

This would read as: "an attribute named id with a text value". Since any attribute can have a value and that the "text" pattern isn't restrictive in this case, it has been made optional and this definition is strictly equivalent to the following one:

  <attribute name="id"/>

The last thing we need to mention about this pattern is that even if in most of the cases the name of the attributes are defined by the "name" attribute or the "attribute" pattern, it is also possible to define sets of possible names for an attribute. This feature will be explained in detail in "Chapter 12: Writing Extensible Schemas".

!!<element/>

Just as the "attribute" pattern matches attributes, the "element" pattern matches elements. To define the "name" element, we will write:

 <element name="name">
  <text/>
 </element>

As mentioned for the "attribute" pattern, it is also possible to replace the "name" attribute of the "element" patter by a set of names as explained in detail in "Chapter 12: Writing Extensible Schemas".

Not all elements accept text nodes and for that reason, the "text" pattern isn't implicit within elements. In fact there is no implicit content for elements and the content of each element must be explicitly described even when the element is always empty.

The fact that a "text" pattern matches zero or more text nodes means that this definition of the "name" element would match empty elements such as:

 <name/>

as well as more traditional names such as:

 <name>Charles M Schulz</name>

We will see in "Chapter 7: Constraining Text Values" how we can add additional restrictions to text nodes to avoid empty elements and in "Chapter 8: Datatype Libraries" how to use the datatypes from W3C XML Schema to add more specific restrictions such as being a valid date.

Attributes can be added within elements and to define the "title" element we will write:

 <element name="title">
  <attribute name="xml:lang"/>
  <text/>
 </element>

We will see the support of namespaces in "Chapter 11: Namespaces" but we can already note how straightforward it is. Here we had to define an attribute (xml:lang) from the XML namespace and we've just added the description of this attribute straight away in out schema. In the case of the XML namespace which is considered as predeclared in any XML document conform to the Namespaces in XML recommendation and implicitly assign the "xml:" prefix to "http://www.w3.org/XML/1998/namespace", we do not need to declare the namespace. In the general case, we would have needed to declare the namespaces using mechanisms described in "Chapter 11: Namespaces".

Note that Relax NG is clever enough to know that attributes are always located in the start tag of XML elements and that their order is not considered as significant. This means that the "attribute" pattern may be located anywhere in the definition of elements and that it would have made no difference if we had written:

 <element name="title">
  <text/>
  <attribute name="xml:lang"/>
 </element>

In addition to text nodes and attributes, elements can also include sub elements and we could define the "author" element as:

 <element name="author">
  <attribute name="id"/>
  <element name="name">
   <text/>
  </element>
  <element name="born">
   <text/>
  </element>
  <element name="died">
   <text/>
  </element>
 </element>

That's not exactly what we want, though since the "born" and "died" elements should have been made optional. To do so, we need to introduce a new pattern:

!!<optional/>

The "optional" pattern just makes its content optional. To specify that the "born" and "died" elements are optional, we will write:

 <optional>
  <element name="born">
   <text/>
  </element>
 </optional>
 <optional>
  <element name="died">
   <text/>
  </element>
 </optional>

Note that this is different from

 <optional>
  <element name="born">
   <text/>
  </element>
  <element name="died">
   <text/>
  </element>
 </optional>

And also different from

 <optional>
  <element name="born">
   <text/>
  </element>
  <optional>
   <element name="died">
    <text/>
   </element>
  </optional>
 </optional>

In the first case, each element is embedded in its own "optional" pattern. The two elements are thus independently optional and I can include both of them, none of them or one of them in valid instance documents. In the second case, both elements are embedded in the same "optional" pattern and we can only include either none of them or both of them in instance documents. In the third case, a first optional pattern includes the "born" element and an optional "died" element meaning that we can find either both of them or none of them in an instance document or the "born" element only but that we forbid the "died" element if the "born" element isn't there.

None of the combinations is "right" or "wrong", they are just different pattern combinations allowing different element combinations in the instance documents and corresponding to different use cases. What's nice with Relax NG is that there are so few restrictions that almost any combination to which you can think of is allowed. To be honest I must admit that there are some few restrictions and they will be covered in "Chapter 15: Simplification And Restrictions".

!!<oneOrMore/>

The "oneOrMore" pattern specifies that its content may appear one or more time. The use case for this pattern in our example is to define that a book must have one or mote authors:

    <oneOrMore>
     <element name="author">
      <attribute name="id"/>
      <element name="name">
       <text/>
      </element>
      <element name="born">
       <text/>
      </element>
      <optional>
       <element name="died">
        <text/>
       </element>
      </optional>
     </element>
    </oneOrMore>

!!<zeroOrMore/>

The last pattern needed in our example is "zeroOrMore" and you'll have guessed that it tells that its content may appear zero or more time like for our "character" elements:

    <zeroOrMore>
     <element name="character">
      <attribute name="id"/>
      <element name="name">
       <text/>
      </element>
      <optional>
       <element name="born">
        <text/>
       </element>
      </optional>
      <element name="qualification">
       <text/>
      </element>
     </element>
    </zeroOrMore>

!!!Complete schema

We have now in hand all the patterns needed to write a full schema expressing all we've said for this example:

 <?xml version = '1.0' encoding = 'utf-8' ?>
 <element xmlns="http://relaxng.org/ns/structure/1.0" name="library">
  <oneOrMore>
   <element name="book">
    <attribute name="id"/>
    <attribute name="available"/>
    <element name="isbn">
     <text/>
    </element>
    <element name="title">
     <attribute name="xml:lang"/>
     <text/>
    </element>
    <oneOrMore>
     <element name="author">
      <attribute name="id"/>
      <element name="name">
       <text/>
      </element>
      <optional>
       <element name="born">
        <text/>
       </element>
      </optional>
      <optional>
       <element name="died">
        <text/>
       </element>
      </optional>
     </element>
    </oneOrMore>
    <zeroOrMore>
     <element name="character">
      <attribute name="id"/>
      <element name="name">
       <text/>
      </element>
      <optional>
       <element name="born">
        <text/>
       </element>
      </optional>
      <element name="qualification">
       <text/>
      </element>
     </element>
    </zeroOrMore>
   </element>
  </oneOrMore>
 </element>

!!Constraining number of occurrences

Those of you familiar with W3C XML Schema will probably have noted that the control over the number of occurrences is specified ala DTD and doesn't have the fine granularity of W3C XML Schema's minOccurs and maxOccurs. Relax NG has been designed in this way because these four cases (exactly once which is the default, optional, zero or more and one or more) are the most common and also because if applications need a finer granularity, they can create it using these four basic occurrence constraints. If for instance, we needed to define that each book's description should include between two and six characters, we could write it as two mandatory characters followed by four optional ones and write:

    <!-- 1 -->
    <element name="character">
     <attribute name="id"/>
     <element name="name">
      <text/>
     </element>
     <optional>
      <element name="born">
       <text/>
      </element>
     </optional>
     <element name="qualification">
      <text/>
     </element>
    </element>
    <!-- 2 -->
    <element name="character">
      .../...
    </element>
    <!-- 3 -->
    <optional>
     <element name="character">
     .../...
      </element>
     </element>
    </optional>
    <!-- 4 -->
    <optional>
     <element name="character">
     .../...
     </element>
    </optional>
    <!-- 5 -->
    <optional>
     <element name="character">
     .../...
     </element>
    </optional>
    <!-- 6 -->
    <optional>
     <element name="character">
     .../...
     </element>
    </optional>

This is certainly verbose but we will see how we can define and reuse patterns to reduce the verbosity.

!!Russian doll schemas

Let's look side by side at the schema and the instance document:

[http://localhost/rngbook/russian-doll.png]

We see that even though information have been added in the schema to describe the content of the text nodes and the number of occurrences, the schema keeps the same hierarchical structure than the instance document.

This type of schema in which the different definitions are embedded in each other (the definition of the "library" element physically contains the definition of the "author element" which physically contains the definition of the "name" element) are often called "Russian doll schemas". We will see in " Chapter 5: Flattening Our First Schema" how Russian doll schemas may be broken into independent patterns combined together to reproduce the structure of the instance document. Before this, we'll have a look in nxet chapter, "Chapter 4: Non XML Syntax" to an alternative, equivalent, compact and non XML syntax for Relax NG.
