Namespaces in XML and XPath

Namespaces provide a simple method for qualifying element and attribute names in XML documents. Namespaces are represented by a namespace URI but, since the URI can be very long, element and attribute names are associated with a namespace using a namespace prefix (see the W3C recommendation for details). In an XML document, a prefix can be associated with a namespace URI using a declaration which takes form of special attribute of the form xmlns:prefix="namespace uri" on an element. The scope of the namespace declaration is then the subtree of the element carrying the special xmlns:prefix attribute (and includes attributes of the element). Moreover, a default namespace can be declared using just xmlns="namespace uri". In that case all unprefixed element names in the scope of such a declaration belong to the namespace. An unprefixed element which is not in scope of a default namespace declaration does not belong to any namespace. It is recommended not to combine namespaced elements and non-namespaced elements in a single document. Note that regardless of default namespace declarations, unprefixed attributes do not belong to any namespace (because they are uniquely determined by their name and the namespace and name of the the element which carries them).

XSH2 tries to deal namespace declarations transparently (creating them if necessary when nodes are copied between different documents or scopes of namespace declarations). Most commands which create new elements or attributes provide means to indicate a namespace. In addition, XSH2 provides commands declare-ns, set-ns, change-ns-uri, and change-ns-prefix to directly manipulate XML namespace declarations on the current node.

Since XSH2 is heavily XPath-based, it is important to remember that XPath 1.0 maps prefixes to namespaces independently of the declarations in the current document. The mapping is instead provided via so called XPath context. Namespaces can be tested in XPath either using the built-in namespace-uri() function, but it is more convenient to use namespace prefixes associated with namespace URIs in the XPath context. This association is independent of the documents to which the XPath expression is applied and can be established using the command register-namespace. Additional, XSH2 automatically propagates the namespace association in the scope of the current node to the XPath context, so that per-document prefixes in the current scope can also be used.

IMPORTANT: XPath 1.0 has no concept of a default namespace. Unprefixed names in XPath only match names which have no namespace. So, if the document uses a default namespace, it is required to associate a non-empty prefix with the default namespace via register-namespace and add that prefix to names in XPath expressions intended to match nodes in the default namespace.

Example 4. Manipulating nodes in XHTML documents

open "index.xhtml";
$xhtmlns = "http://www.w3.org/1999/xhtml";
register-namespace x $xhtmlns;
wrap --namespace $xhtmlns '<font color="blue">' //x:a[@href];
# or 
wrap '<x:font color="blue">' //x:a[@href];

In the preceding example we associate the (typically default) namespace of XHTML documents with the prefix x. We than use this prefix to match all links (a elements) in the document. Note that we do not write @x:href to match the @href attribute because unprefixed attributes do not belong to the default namespace. The wrap command is used to create new containing elements for the nodes matched by the XPath expression. We may either specify the namespace of the containing element explicitly, using --namespace option, or implicitly, by using a prefix associated with the namespace in the XPath context. In the latter case, XSH2 chooses a suitable prefix declared for the namespace in the document scope (in this case the default, i.e. no, prefix), adding a new namespace declaration if necessary.

Related topics

change-ns-prefix

change namespace prefix (EXPERIMENTAL)

change-ns-uri

change namespace URI (EXPERIMENTAL)

declare-ns

create a special attribute declaring an XML namespace (EXPERIMENTAL)

namespaces

List namespaces available in a context of a given nodes

register-namespace

register namespace prefix to use XPath expressions

register-xhtml-namespace

register a prefix for the XHTML namespace

register-xsh-namespace

register a prefix for the XSH2 namespace

set-ns

set namespace of the current node (EXPERIMENTAL)

unregister-namespace

unregister namespace prefix