Assembling Queries from Multiple Modules

So far, all of this book's example queries were contained in one module, known as the main module. However, you can declare functions and variables in other modules and import them into the main module of the query. This is a very useful feature for:

  • Reusing functions among many queries

  • Creating standardized libraries that can be distributed to a variety of query users

  • Organizing and reducing the size of query modules

The main module contains a query prolog followed by a query body, which is the main expression to be evaluated. In its prolog, the main module can import other modules known as library modules.

Not all implementations support the use of library modules; it is an optional feature.

Library Modules

Library modules differ from main modules in that they cannot have a query body, only a prolog. They also differ in that they must start with a module declaration, whose syntax is shown in Figure 12-2.

Syntax of a module declaration

Figure 12-2. Syntax of a module declaration

The module declaration identifies the module as a library module. It also declares the target namespace of the module and maps it to a prefix. For example, the expression:

module namespace strings = "http://datypic.com/strings";

declares the target namespace of the module to be http://datypic.com/strings and binds that namespace to the prefix strings.

The target namespace must be a literal value in quotes, not an evaluated expression. It should be a syntactically valid absolute URI, and cannot be a zero-length string.

All of the functions and variables declared in that library module must be qualified with that same target namespace. This differs from main modules, which do not have target namespaces and allow you to declare variables and functions in a variety of namespaces.

This is shown in Example 12-3, where the variable and function names are prefixed with strings.

Example 12-3. Module

module namespace strings = "http://datypic.com/strings";
declare variable $strings:maxStringLength := 32;
declare function strings:trim($arg as xs:string?) as xs:string? {
  "function body here"
};

Importing a Library Module

Both main modules and library modules can import other library modules. Importing a library module allows its variables and functions to be referenced from the importing module. Only library modules can be imported; a main module can never be imported by another module.

A module import, which appears in the prolog, specifies the target namespace and location of the library module to be imported. Multiple module imports can appear in the query prolog. (The syntax of a module import is shown in Figure 12-3.)

Syntax of a module import

Figure 12-3. Syntax of a module import

For example, the declaration:

import module "http://datypic.com/strings"
           at "http://datypic.com/strings/lib.xq";

imports the module from http://datypic.com/strings/lib.xq whose target namespace is http://datypic.com/strings. The target namespace specified in the module import must match the target namespace of the library module that is being imported. The module location and namespace must be literal values in quotes (not evaluated expressions), and they should be syntactically valid absolute URIs.

Imported modules can have the same target namespace as the importing module, or they can have a different one. For convenience, it is also possible to map a namespace prefix directly in the module import. For example:

import module namespace strings = "http://datypic.com/strings"
                        at "http://datypic.com/strings/lib.xq";

binds the prefix strings to the namespace, in addition to importing the module.

The at keyword and location are optional. If the processor has some other way to locate the module based on its target namespace, it can be omitted. In fact, the processor is not required to use the location even if it is provided.

Multiple module imports

It is possible to specify multiple module locations for the same target namespace in a single import, using commas to separate them, as in:

import module "http://datypic.com/strings"
               at "http://datypic.com/strings/lib.xq",
                  "http://datypic.com/strings/lib2.xq";

This syntax is the only way to specify multiple imports for the same target namespace. If two separate module imports specify the same target namespace, an error is raised.

Function signatures and variable names must be unique across all modules that are used together (main or imported). Declaring two functions with the same qualified name and the same number of parameters raises an error, as does declaring two variables with the same qualified name. These errors are raised even if the two duplicate declarations are exactly the same.

Library modules can import other library modules, even ones with the same target namespace. However, circular module imports are not allowed unless all modules imported in the circle have the same target namespace. This means you need to plan the assignment of functions to modules with great care. For example, if you have a module for manipulating postal codes and another for manipulating geographical coordinates, and if each of these modules needs to reference functions in the other module, then you will have to either put them in the same namespace or move some shared components to a third, neutral namespace.

The behavior of a module import

It is important to understand that a module import only imports the function and variable declarations of the library module. It does not import any schemas or other modules that are imported in the prolog of the library module.

For example, suppose the strings.xq library module contains an import of a third module, called characters.xq. If the main module imports strings.xq, that does not mean that characters.xq is also imported into the main module. If the main module refers to the functions and variables of characters.xq directly, it needs to have a separate module import for characters.xq.

Likewise, if strings.xq imports a schema named stringtypes.xsd, the main module that imports strings.xq must also separately import the schema if it refers to any types from that schema. This is described further in the section "Schema Imports" in Chapter 13.

..................Content has been hidden....................

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