Namespace declarations in a RELAX NG schema follow the same principles as namespace declarations in an instance document, with some small differences in the syntax. RELAX NG supports the use of both the default namespace and prefixes.
The namespace on
which a schema expects to operate in the
instance document can be defined through the ns
attribute. Like the datatypeLibrary
attribute seen
earlier, ns
is an inherited attribute. Being
inherited means that you can define it in the document element of the
schema (and never again) if it remains the same throughout the
schema. For instance, to write a schema for the first example in this
chapter, in which the entire library is using the same namespace, I
can write:
<?xml version="1.0" encoding="utf-8"?> <element xmlns="http://relaxng.org/ns/structure/1.0" name="library" ns="http://eric.van-der-vlist.com/ns/library"> <oneOrMore> <element name="book"> <attribute name="id"/> ... </element> </oneOrMore> </element>
The compact syntax uses a slightly different declaration,
default namespace
, at the top of the schema:
default namespace = "http://eric.van-der-vlist.com/ns/library" element library { element book { attribute id { text }, ... }* }+ }
The definition of the default namespace in a RELAX NG schema doesn’t apply to attributes. This works precisely as expected, because the default namespace doesn’t apply to attributes in instance documents and should cause a minimum of surprises.
Just as default namespaces can be used and changed all over a
multinamespace document, when using the XML syntax, the
ns
attribute can be changed in a schema. To
validate the documents with the two namespaces shown in
Section 11.1, I can write:
<?xml version="1.0" encoding="utf-8"?> <element xmlns="http://relaxng.org/ns/structure/1.0" name="library" ns="http://eric.van-der-vlist.com/ns/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> <zeroOrMore> <element name="author" ns="http://eric.van-der-vlist.com/ns/person"> <attribute name="id"/> <element name="name"> <text/> </element> <element name="born"> <text/> </element> <optional> <element name="dead"> <text/> </element> </optional> </element> </zeroOrMore> <zeroOrMore> <element name="character"> <attribute name="id"/> <element name="name" ns="http://eric.van-der-vlist.com/ns/person"> <text/> </element> <element name="born" ns="http://eric.van-der-vlist.com/ns/person"> <text/> </element> <element name="qualification"> <text/> </element> </element> </zeroOrMore> </element> </oneOrMore> </element>
The compact syntax doesn’t provide a way to redefine the default namespace. Defining prefixes is the preferred way to define schemas with multiple namespaces when using the compact syntax.
Because the three variations used to write the document with the two namespaces in Section 11.1 are considered equivalent to namespace-aware applications, the schema just written will validate all of them. There is thus complete independence between the prefixes and default namespaces used to write the instance document, and those used in the schema. Namespace matching tests only the namespace URIs of each element and attribute, not the prefixes.
The definition of the default target namespace in RELAX NG
is done through an ns
attribute, and thus
doesn’t rely on the declaration of the default
namespace of the RELAX NG document itself. (In our examples, the
default namespace of the RELAX NG document is the RELAX NG
namespace.) The declaration of the prefixes used for target
namespaces other than the default is done through namespace
declarations like those used in instance documents. In other words,
to define an hr
prefix, which is used as a prefix
for the namespaces in names or attributes of the instance, I use an
xmlns:hr
declaration as if I wanted to use it as a
prefix for an element or attribute of the RELAX NG document.
You can mix both default and nondefault namespaces and write:
<?xml version="1.0" encoding="utf-8"?> <element xmlns="http://relaxng.org/ns/structure/1.0" name="library" ns="http://eric.van-der-vlist.com/ns/library" xmlns:hr="http://eric.van-der-vlist.com/ns/person"> <!-- The default target namespace is "http://eric.van-der-vlist.com/ns/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> <zeroOrMore> <element name="hr:author"> <!-- Here we are using a "hr" prefix to match "http://eric.van-der-vlist.com/ns/ person" --> <attribute name="id"/> <element name="hr:name"> <text/> </element> <element name="hr:born"> <text/> </element> <optional> <element name="hr:dead"> <text/> </element> </optional> </element> </zeroOrMore> <zeroOrMore> <element name="character"> <attribute name="id"/> <element name="hr:name"> <text/> </element> <element name="hr:born"> <text/> </element> <element name="qualification"> <text/> </element> </element> </zeroOrMore> </element> </oneOrMore> </element>
The compact syntax uses its own declaration to define namespace prefixes:
default namespace = "http://eric.van-der-vlist.com/ns/library" namespace hr = "http://eric.van-der-vlist.com/ns/person" element library { element book { attribute id { text }, attribute available { text }, element isbn { text }, element title { attribute xml:lang { text }, text }, element hr:author { attribute id { text }, element hr:name { text }, element hr:born { text }, element hr:dead { text }? }*, element character { attribute id { text }, element hr:name { text }, element hr:born { text }, element qualification { text } }* }+ }
Again, this schema validates the three variations seen in Section 11.1. In fact, this schema validates exactly the same set of documents as the schema using only default namespaces. A third equivalent variation uses prefixes for both namespaces:
<?xml version="1.0" encoding="utf-8"?> <element xmlns="http://relaxng.org/ns/structure/1.0" name="lib:library" xmlns:lib="http://eric.van-der-vlist.com/ns/library" xmlns:hr="http://eric.van-der-vlist.com/ns/person"> <oneOrMore> <element name="lib:book"> <attribute name="id"/> <attribute name="available"/> <element name="lib:isbn"> <text/> </element> <element name="lib:title"> <attribute name="xml:lang"/> <text/> </element> <zeroOrMore> <element name="hr:author"> <attribute name="id"/> <element name="hr:name"> <text/> </element> <element name="hr:born"> <text/> </element> <optional> <element name="hr:dead"> <text/> </element> </optional> </element> </zeroOrMore> <zeroOrMore> <element name="lib:character"> <attribute name="id"/> <element name="hr:name"> <text/> </element> <element name="hr:born"> <text/> </element> <element name="lib:qualification"> <text/> </element> </element> </zeroOrMore> </element> </oneOrMore> </element>
or:
namespace lib = "http://eric.van-der-vlist.com/ns/library" namespace hr = "http://eric.van-der-vlist.com/ns/person" element lib:library { element lib:book { attribute id { text }, attribute available { text }, element lib:isbn { text }, element lib:title { attribute xml:lang { text }, text }, element hr:author { attribute id { text }, element hr:name { text }, element hr:born { text }, element hr:dead { text }? }*, element lib:character { attribute id { text }, element hr:name { text }, element hr:born { text }, element lib:qualification { text } }* }+ }
Again, this schema is equivalent to the previous ones because it validates all the variations of namespaces declarations in the instance documents.
18.224.37.89