By Eric van der Vlist
Price: $29.95 USD
£20.95 GBP
Cover | Table of Contents | Colophon
http://www.thaiopensource.com/relaxng/trang.html).<book
id='b0836217462'
available="true"/> is an empty tag containing
two attributes named id and
available. The value of id is
delimited with single quotes, while the value of
available is delimited with double quotes. Yet,
from an infoset perspective, this isn't an empty tag
with particular syntax; the kind of quotation marks
don't matter. It's a
book element with an attribute named
id and a value of b0836217462,
as well as an attribute named available with a
value of true. Elements, attributes, and text are
often referred to as
nodes
in this perspective, like nodes in an object tree.<book
id='b0836217462'
available="true"/> is an empty tag containing
two attributes named id and
available. The value of id is
delimited with single quotes, while the value of
available is delimited with double quotes. Yet,
from an infoset perspective, this isn't an empty tag
with particular syntax; the kind of quotation marks
don't matter. It's a
book element with an attribute named
id and a value of b0836217462,
as well as an attribute named available with a
value of true. Elements, attributes, and text are
often referred to as
nodes
in this perspective, like nodes in an object tree.http://www.w3.org/TR/xml-infoset/. The XML
Infoset defines an abstract model of XML documents that uses a
hierarchical structure described in terms generic and neutral enough
to be acceptable for use with a diverse range of specifications.book must have an attribute named
id and this attribute's content
must match this specific rule...."book, and it has two attributes named
id and available, which look
like this...."book element with its two attributes and four
different subelements:
book element into a first pattern composed of
the attributes id, title, and
author and the element
character, and then a second pattern composed of
the available attribute and the other
character elements.
data, which
can be limited to particular datatypes and possibly be split into
list items. Lastly, a whole set of features supports the creation of
reusable libraries of patterns. Similar to patterns, name
classes
define sets of elements and attributes
that can be used to open a schema and control where elements and
attributes with unknown names may be included in the instance
documents.<?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>
<character id="Lucy">
<name>Lucy</name>
<born>1952-03-03</born>
<qualification>bossy, crabby and selfish</qualification>
</character>
</book>
</library>
library element composed of:book elements having:id attribute and an
available attributeisbn element composed of text
<?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>
<character id="Lucy">
<name>Lucy</name>
<born>1952-03-03</born>
<qualification>bossy, crabby and selfish</qualification>
</character>
</book>
</library>
library element composed of:book elements having:id attribute and an
available attributeisbn element composed of text
title element with an
xml:lang attribute and a text nodeauthor elements with:id attributename elementborn elementdied elementcharacter elements with:id attributename elementborn elementqualification element` <?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>
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>
element or
attribute, and their RELAX NG pattern name.
Optionally, one or more, and zero or more elements or attributes are
represented by DTD qualifier suffixes (? for
optional, text is the simplest pattern in the XML syntax and
is the simplest in the compact syntax as well. The
text
pattern is just:text
text identifies the
text pattern.text in
RELAX NG's XML syntax also applies to
text in the compact syntax.attribute
pattern borrows Java's
curly brackets: attribute id { text }
attribute,
identifies the attribute pattern; the second one,
id, is the name of the attribute. The curly
brackets, {...}, delimit the definition of the
content of the attribute.{}) look weird and
might imply empty attributes rather than attributes containing a text
value, the convention of the XML syntax that makes a text pattern the
implicit content for attributes is abandoned in the compact syntax.
The content of attributes must be explicitly defined when
you're using the compact syntax. In other words, in
the compact system, the following:<attribute name="id"/>
attribute id { text }
attribute id { }
text and attribute are reserved
words only when they appear in the first position. This is very
convenient when you need to define attributes (or elements) that have
names that are the same as reserved words. For instance, you can
define attributes named text or even
attribute without any precaution such as:attribute text { text }
attribute attribute { text }element library {
element book {
attribute id { text },
attribute available { text },
element isbn { text },
element title {
attribute xml:lang { text },
text
},
element author {
attribute id { text },
element name { text },
element born { text }?,
element died { text }?
}+,
element character {
attribute id { text },
element name { text },
element born { text }?,
element qualification { text }
}*
}+
}
text, element, or
attribute elements into the schema each time a
text node, element, or attribute was encountered in the instance
document. This method of creating schemas can be seen as a
serialization of the XML infoset
(i.e., of the structure available in the document) and could,
therefore, be easily automated.name element that uses
the same model within both the character and
author elements.name means in each
context:
name element is simple, and thus not verbose. The
principle is the same if the definition is complex, however. It will
require redundancy. This
redundancy makes
maintenance of the schema more error-prone. If I need to update the
definition of the name element,
I'll need to update it as many times at it appears,
but I'll give myself more room for mistakes. Common
sense applies the same rules to XML schema languages as to any
programming language. Limiting repetitive work makes developers
happy!define
elements. To define named patterns that contain the
title element, write:<define name="title-element"> <element name="title"> <text/> </element> </define>
title-element = element title {text}
id attribute, a
name element, and an optional
born element are present in the same order and
with the same definition in both the author and
the character element.
<define name="common-content"> <attribute name="id"/> <element name="name"> <text/> </element> <optional> <element name="born"> <text/> </element> </optional> </define>
common-content =
attribute id { text },
element name { text },
element born { text }?
ref element. For
instance, to define the author element, use a
reference to the name-element pattern: <element name="author">
<attribute name="id"/>
<ref name="name-element"/>
<optional>
<element name="born">
<text/>
</element>
</optional>
<optional>
<element name="died">
<text/>
</element>
</optional>
</element>
element author {
attribute id { text },
name-element,
element born { text }?,
element died { text }?
}
common-content
named pattern: <element name="author">
<ref name="common-content"/>
<optional>
<element name="died">
<text/>
</element>
</optional>
</element>
element author {
common-content,
element died { text }?
}
library
element) is used as a container for the whole schema. When you define
named
patterns, you need a container to embed both the named pattern
definitions and the definition of the root element of the named
patterns. This definition of the root element, as well as definitions
of all the patterns that may be used within it, is what RELAX NG
calls a grammar. It uses the
grammar
element. When you use a grammar element, RELAX NG
requires you to explicitly declare the root element or elements,
using a start
element. An incomplete skeleton of the
structure of the schema defining a pattern
name-element would thus be:<grammar xmlns="http://relaxng.org/ns/structure/1.0"> <start> <element name="library"> .../... </element> </start> <define name="name-element"> .../... </define> </grammar>
grammar {
name-element = .../...
start =
element library {
.../...
}
}
grammar pattern is
implicit. You can use it, but it isn't required.