Namespace Declarations in Queries

There are three ways that namespaces are mapped to prefixes in XQuery queries:

  • Some namespaces are predeclared; no explicit namespace declaration is necessary to associate a prefix with the namespace.

  • Namespace declarations can appear in the query prolog.

  • Namespace declarations can appear in direct XML constructors.

The examples in this section use the input document cat_ns.xml shown in Example 10-4.

Predeclared Namespaces

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

Prefix

Namespace

Uses

xml

http://www.w3.org/XML/1998/namespace

XML attributes such as xml:lang and xml:space

xs

http://www.w3.org/2001/XMLSchema

XML Schema built-in types and their constructors

xsi

http://www.w3.org/2001/XMLSchema-instance

XML Schema instance attributes such as xsi:type and xsi:nil

fn

http://www.w3.org/2005/xpath-functions

XPath Functions Namespace: the default namespace of all built-in functions

local

http://www.w3.org/2005/xquery-local-functions

Functions declared in a main module that are not in a specific namespace

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.

Prolog Namespace Declarations

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.

Syntax of a prolog namespace declaration

Figure 10-1. Syntax of a prolog namespace declaration

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.

Default namespace declarations in the prolog

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.

Syntax of a prolog default namespace declaration

Figure 10-2. Syntax of a prolog default namespace declaration

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.

The default function namespace declaration

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.

Other prolog namespace declarations

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.

Namespace Declarations in Element Constructors

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.

The Impact and Scope of Namespace Declarations

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.

Scope of namespace declarations

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.

Names affected by namespace declarations

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.

Important

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

  

Namespace declarations and input elements

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.

Example 10-11. Simple product example in namespace (prod_ns.xml)

<prod:product xmlns:prod="http://datypic.com/prod">
  <prod:number>563</prod:number>
  <prod:name language="en">Floppy Sun Hat</prod:name>
</prod:product>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.70.38