You now have all the patterns needed to write a full schema that expresses what we’ve discussed about 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>
RELAX NG directly supports four kinds of
occurrence constraints on nodes: they
may appear as exactly once (the default), optional, zero or more, or
one or more. These are the most common cases in document design. If
applications need a finer level of control, that can be achieved by
using or combining these four basic occurrence constraints. If, for
instance, you need to define that each book’s
description should have between two and six
character
elements, you can write the definition
as two mandatory characters followed by four optional ones:
<!-- 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 in later chapters, you will see how to define and reuse patterns to reduce verbosity.
Figure 3-1 shows the schema and the instance document side by side. Even though information has been added to the schema that describes the content of the text nodes and the number of their occurrences, the schema keeps the same hierarchical structure as the instance document.
A schema in which different definitions are embedded in each other,
like this one, in which the definition of the
library
element physically contains the definition
of the author
element that physically contains the
definition of the name
element—is often
called a
Russian doll
schema
after the
nested matruschka dolls. In Chapter 5, you’ll see how Russian doll
schemas can be broken into independent patterns and then combined to
reproduce the structure of the instance document. First,
we’ll examine the equivalent compact syntax for
RELAX NG in the next chapter.
3.143.205.169