There are three ways that namespaces are mapped to prefixes in XQuery queries:
The examples in this section use the input document cat_ns.xml
shown in Example 10-4.
For convenience, five commonly used namespace declarations are built into the XQuery recommendation. They are listed in Table 10-1. The five prefixes can be used anywhere in a query even if they are not explicitly declared by a namespace declaration. These prefixes are also used throughout this book to represent the appropriate namespaces.
Table 10-1. Predeclared namespaces
In addition, your XQuery implementation may predeclare other namespaces for use within your queries or allow users to predeclare other namespaces by means of an API. Consult the documentation for your implementation to determine what, if any, other namespaces are predeclared.
Namespaces can be declared in the query prolog. The syntax of a namespace declaration in the query prolog, shown in Figure 10-1, is different from a typical XML namespace declaration. For example:
declare namespace cat = "http://datypic.com/cat";
maps the prefix cat
to the namespace http://datypic.com/cat.
This mapping applies to all names in the entire query, including element names, attribute names, function names, variable names, and type names.
Example 10-6 makes use of two prolog namespace declarations:
The rep
prefix is mapped to a namespace that is to be used for a newly constructed element, report
. The report
constructor uses a prefix to indicate that it is that namespace.
The prod
prefix is mapped to a namespace used in the input document. This declaration is necessary so that the path expression step prod:product
can associate the name product
with the correct namespace.
Note that the http://datypic.com/cat namespace does not need to be declared in the query (even though it is used in the input document), because it is not used in any names in the query itself. It does appear in the results, even though it is not associated with any names in the results. This is explained further in "Controlling Namespace Declarations in Your Results," later in this chapter.
Example 10-6. Prolog namespace declarations
Query
declare namespace rep = "http://datypic.com/report"; declare namespace prod = "http://datypic.com/prod"; <rep:report> { doc("cat_ns.xml")//prod:product } </rep:report>Results
<rep:report xmlns:rep="http://datypic.com/report"> <prod:product xmlns="http://datypic.com/cat" xmlns:prod="http://datypic.com/prod"> <prod:number>563</prod:number> <prod:name language="en">Floppy Sun Hat</prod:name> </prod:product> </rep:report>
The namespace name in a namespace declaration must be a literal value (in quotes), not a variable reference or other evaluated expression. The value should be a syntactically valid absolute URI.
You can also declare default namespaces in the prolog, using the syntax shown in Figure 10-2. There are two different default namespace declarations, one for elements and types, and the other for functions.
For example:
declare default element namespace "http://datypic.com/cat";
would make http://datypic.com/cat the default namespace for elements and types. This means that anywhere an unprefixed element or type name is used in the query (for example, in element constructors and path expressions), it is assumed to be in that namespace.
This is shown in Example 10-7, which is the same as Example 10-6 except with an added default namespace declaration and a new step catalog
in the path expression. The results are the same as those returned by Example 10-6. In this case, because catalog
is unprefixed, the processor will look for a catalog
element in the default element namespace, http://datypic.com/cat.
Example 10-7. Prolog default namespace declaration
declare default element namespace "http://datypic.com/cat";
declare namespace rep = "http://datypic.com/report";
declare namespace prod = "http://datypic.com/prod";
<rep:report> {
doc("cat_ns.xml")/catalog/prod:product
} </rep:report>
In Example 10-7, it just so happens that the namespace declarations in the query match the namespace declarations in the input document. The namespace http://datypic.com/prod is mapped to the prod
prefix, and http://datypic.com/cat is the default, in both places.
However, it is not necessary for the prefixes to match. Example 10-8 shows an equivalent query where a different prefix is used for the namespace http://datypic.com/prod, and http://datypic.com/cat now has a prefix associated with it too. Note that the prefixes declared in the query (prod2
and cat
) are used in the path expression, not those from the input document. In fact, it would be illegal to use the prod
prefix in this query, because it is not declared in the query itself.
Example 10-8. Namespace declarations in query different from input document
declare namespace rep = "http://datypic.com/report"; declare namespace cat = "http://datypic.com/cat"; declare namespace prod2 = "http://datypic.com/prod"; <rep:report> { doc("cat_ns.xml")/cat:catalog/prod2:product } </rep:report>
Example 10-8 yields the same results as Example 10-7. It is worth noting that the prod
prefix (from the input document) is used in the results rather than prod2
(from the query).
As with a regular XML default namespace declaration, a prolog default element namespace declaration does not apply to attribute names, nor does it apply to variable names or function names.
Only one default element namespace declaration may appear in the query prolog. If the string literal is a zero-length string, unprefixed element and type names are considered to be in no namespace.
You can also declare a default namespace for functions, using the same syntax, but with the keyword function
. For example:
declare default function namespace "http://datypic.com/funclib";
This means that all unprefixed functions that are called or declared within that query (including type constructors) are assumed to be in that namespace. If you specify a zero-length string, the default will be "no namespace." Only one default function namespace declaration may appear in the query prolog.
If no default function namespace is declared, the default is the XPath Functions Namespace,
http://www.w3.org/2005/xpath-functions. In general, it is best not to override this, because if you do, you are required to prefix all calls to the built-in functions such as substring
and max
.
For convenience, other prolog declarations can bind namespaces to prefixes, namely schema imports, module declarations, and module imports. For example:
import module namespace strings = "http://datypic.com/strings" at "http://datypic.com/strings/lib.xq";
will bind the http://datypic.com/strings namespace to the strings
prefix. These types of declarations are covered in Chapters 12 and 13.
Namespaces can also be declared in direct element constructors, using the regular XML attributes whose names start with xmlns
. These are known as namespace declaration attributes
in XQuery, and are shown in Example 10-9.
Example 10-9. Using namespace declaration attributes
Query
<rep:report xmlns="http://datypic.com/cat" xmlns:prod="http://datypic.com/prod" xmlns:rep="http://datypic.com/report"> { doc("cat_ns.xml")/catalog/prod:product } </rep:report>Results
<rep:report xmlns:rep="http://datypic.com/report" xmlns:prod="http://datypic.com/prod" xmlns="http://datypic.com/cat"> <prod:product> <prod:number>563</prod:number> <prod:name language="en">Floppy Sun Hat</prod:name> </prod:product> </rep:report>
The location of the namespace declarations in the results of Example 10-9 are different from those of Example 10-7, although the two results are technically equivalent. This subtle difference is explained in "Controlling Namespace Declarations in Your Results," later in this chapter.
As with prolog namespace declarations, the namespace name used in a namespace declaration attribute must be a literal value, not an enclosed expression, and it should be a syntactically valid absolute URI. Namespace declaration attributes with prefixes whose values are zero-length strings, such as xmlns:cat=""
, are only allowed if the implementation supports Namespaces 1.1.
As in XML documents, namespace declarations in queries have a scope and a set of names to which they are applicable. This section describes the scope and impact of namespace declarations in XQuery, whether they are in the prolog or in direct element constructors.
The scope of a namespace declaration in an element constructor is the constructor itself (including any other attributes, whether they appear before or after the namespace declaration). Much like regular XML documents, namespace declarations in child element constructors can override the namespace declarations of the outer constructors. However, this is not recommended.
The scope of a prolog namespace declaration is the entire query module. However, prolog namespace declarations can also be overridden, by namespace declarations in an element constructor. For example, if in Example 10-7 you placed a default namespace declaration in the report
start tag, it would be in scope until the report
end tag (including any attributes of report
), overriding the default namespace declaration in the prolog.
Whether namespace declarations appear in the prolog or in a direct element constructor, they have similar rules regarding the names on which they have an effect. Namespace declarations that specify a prefix (i.e., ones that are not default namespace declarations) allow that prefix to be used with any qualified name, namely:
The element and attribute names that are constructed in the query, like rep:report
The element and attribute names from the input document that are used in path expressions, such as cat:catalog
and prod:product
Type names that are used in function signatures and in type-related expressions such as constructors or instance of
expressions
The names of functions, in both function calls and function declarations
The names of variables, both when they are bound and when they are referenced
Default element namespace declarations affect only element and type names. They do not affect attribute, variable, or function names. Attribute and variable names, when they appear unprefixed, are considered to be in no namespace, not the default element namespace. Unprefixed function names are in the default function namespace.
The fact that element names in XQuery paths are affected by default namespace declarations is different from XSLT. In XSLT, a default namespace declaration does not affect element names in path expressions. For example, in XQuery:
<abc xmlns="xyz">{$root/d/e}</abc>
the processor will look for the d
and e
elements in the xyz
namespace. In XSLT:
<abc xmlns="xyz"> <xsl:copy-of select="$root/d/e"/> </abc>
the processor will look for the d
and e
elements in no namespace.
These rules governing the impact of namespace declarations on names are summarized in Table 10-2.
Table 10-2. Impact of namespace declarations on names
Variety of namespace declaration |
Element |
Attribute |
Type |
Function/type constructor |
Variable |
---|---|---|---|---|---|
Predeclared namespaces |
y |
y |
y |
y |
y |
Prolog namespace declaration (with prefix) |
y |
y |
y |
y |
y |
Prolog default element namespace |
y |
y | |||
Prolog default function namespace |
y | ||||
Namespace declaration attribute (with prefix) |
y |
y |
y |
y |
y |
Namespace declaration attribute (default) |
y |
y |
It is important to understand that namespace declarations in a query affect only names that are explicitly specified in that query, not those of any child elements that might be included from the input document. Example 10-10 shows a query that copies some elements from an input document into a newly constructed element. It uses the input document prod_ns.xml
shown in Example 10-11. The input document elements (names
and name
) are in the http://datypic.com/prod namespace, while the constructed report
element is in the http://datypic.com/report namespace.
Example 10-10. Namespace declaration impact on input elements
Query
<report xmlns="http://datypic.com/report"> <firstChild/> {doc("prod_ns.xml")/*} </report>Results
<report xmlns="http://datypic.com/report"> <firstChild/> <prod:product xmlns:prod="http://datypic.com/prod"> <prod:number>563</prod:number> <prod:name language="en">Floppy Sun Hat</prod:name> </prod:product> </report>
In the results, report
and firstChild
are in the default namespace specified in the query. However, the product
, number
, and name
elements are still in their original namespace from the input document. They do not become part of the default http://datypic.com/prodreport namespace. This would be true even if they were in no namespace in the input document. Copying an element never changes its namespace.
3.145.70.38