With regard to modes, the interesting part of the standard is § 6.4.7. “The top-level rules element is transformed so that it has mode elements as children. If its child elements are namespace or anyNamespace elements, they are wrapped in a mode element. Then, a name attribute and startMode attribute are added to the mode element and rules element, respectively. These attributes shall have the same value, which shall be different from any other mode name. ” This implies that as far as processing goes, your script will have modes, whether you want them or not. The subtlety is that the modes may not do what you want. I hope this was demonstrated if you tried re-ordering the sections in the previous chapter, as noted here.
The previous examples have simply used namespace elements to partition the input instance for
validation. This statement makes it clear that as part of the process,
all namespace elements are wrapped in mode elements. So either way, your scripts will
use modes.
The simplest exlanation of is to imagine a chain of modes. From
the rules element the first mode is
specified by the startMode attribute on
the rules element. Each mode element can specify the mode to change to
next, by means of the useMode attribute
on the validate or anyelement, the child of mode. The namespaced based processing follows this
chain by looking at the children of the current node in the XML
instance, and when a non-matching namespace is found, the next in
chain mode is used. This works well for nested elements, less well
when two different namespaces are used as siblings? Imagine the head
and body elements of XHTML being in different namespaces? For such as
this, the two namespaces need to be handled in the same mode.
Taking Example 2.9, “The NVDL script for Example 2.4” as a starting point,
it can be written as a moded script, see Example 3.1
Example 3.1. A moded version of Example 2.9
<rules xmlns="http://purl.oclc.org/dsdl/nvdl/ns/structure/1.0" startMode="doc"><mode name="doc">
<namespace ns="http://document"> <validate schema="routing.1.rng" useMode="rest"/> </namespace> </mode> <mode name="rest">
<namespace ns="http://head" > <validate schema="routing.1.rng" /> </namespace> <namespace ns="http://body">
<validate schema="routing.1.rng" /> </namespace> </mode> </rules>
I hope this example is clear. Imagine the source XML
instance. View it as a tree of namespaces (rather than just
elements). For each child in the tree, a new mode
is needed in a simple moded ruleset. For each sibling namespace, the
dispatcher needs to be told how to validate it within a single mode
that handles all sibling namespaces. As you walk the tree, imagine the
changing namespaces and the way through the rules via the different
modes you specify. Note the lack of a useMode attribute on the two siblings? We don't
want to change modes on meeting a foreign namespace, we need to remain
in this mode. You could say that after meeting the 'head' namespace,
we come across the 'body namespace' in the source instance, the
processor tries again in the same mode. The key point is that the
processing remains in this mode until a foreign namespace is
encountered for which it has no matching condition (a namespace match
in this mode).
Yet again we need to mention the default rule. This is there to reject all foreign namespaces for which you have not created a rule.
<anyNamespace> <reject/> </anyNamespace>