In-scope namespaces of a constructed element

A constructed element node has an in-scope namespaces property that consists of a set of namespace bindings. Each namespace binding associates a namespace prefix with a URI. The namespace bindings define the set of namespace prefixes that are available for interpreting qualified names (QNames) within the scope of an element.

Important: To understand this topic, you need to understand the difference between the following concepts:
Statically known namespaces
Statically known namespaces is a property of an expression. This property denotes the set of namespace bindings that are used by XQuery to resolve namespace prefixes during the processing of the expression. These bindings are not part of the query result.
In-scope namespaces
In-scope namespaces is a property of an element node. This property denotes the set of namespace bindings that are available to applications outside of XQuery when the element and its content are processed. These bindings are serialized as part of the query result so that they are available to outside applications.
The in-scope namespaces of a constructed element include all of the namespace bindings that are created in the following ways:
  • Explicitly, through namespace declaration attributes

    A namespace binding is created for each namespace declaration attribute that is declared in the following constructors:

    • The current element constructor
    • An enclosing direct element constructor, unless the namespace declaration attribute is overridden by the current element constructor or an intermediate constructor
  • Automatically, by the system

    A namespace binding is created in the following situations:

    • For every constructed element, to bind the prefix xml to the namespace URI http://www.w3.org/XML/1998/namespace
    • For each namespace that is used in the name of a constructed element or in the names of its attributes, unless the namespace binding already exists in the in-scope namespaces of the element. If the name of the node includes a prefix, the prefix is used in the namespace binding. If the name has no prefix, a binding is created for the empty prefix. If a conflict arises that would require two different bindings of the same prefix, the prefix that is used in the node name is changed to an arbitrary prefix, and the namespace binding is created for the arbitrary prefix.
      Important: A prefix that is used in a QName must resolve to a valid URI. Otherwise, a binding for that prefix cannot be added to the in-scope namespaces of the element. If the QName cannot be resolved, the expression results in an error.

Examples

The following query includes a prolog that contains namespace declarations and a body that contains a direct element constructor:
SELECT XMLQUERY(
 'declare namespace p="http://example.com/ns/p";
  declare namespace q="http://example.com/ns/q";
  declare namespace f="http://example.com/ns/f";
  <p:newElement q:b="B900" xmlns:r="http://example.com/ns/r"/>')
FROM SYSIBM.SYSDUMMY1
The namespace declarations in the prolog add the namespace bindings to the statically known namespaces of the expression. However, the namespace bindings are added to the in-scope namespaces of the constructed element only if the QNames in the constructor use these namespaces. Therefore, the in-scope namespaces of p:newElement consist of the following namespace bindings:
  • p = "http://example.com/ns/p" - This namespace binding is added to the in-scope namespaces because the prefix p appears in the QName p:newElement.
  • q = "http://example.com/ns/q" - This namespace binding is added to the in-scope namespaces because the prefix q appears in the attribute QName q:b.
  • r = "http://example.com/ns/r" - This namespace binding is added to the in-scope namespaces because it is defined by a namespace declaration attribute.
  • xml = "http://www.w3.org/XML/1998/namespace" - This namespace binding is added to the in-scope namespaces because it is defined for every constructed element node.

No binding for the namespace f="http://example.com/ns/f" is added to the in-scope namespaces. This is because the element constructor does not include element or attribute names that use the prefix f. Therefore, this namespace binding does not appear in the query result, even though it is present in the statically known namespaces and is available for use during processing of the query.

The query returns the following result:

<p:newElement xmlns:q="http://example.com/ns/q"
              xmlns:r="http://example.com/ns/r"
              xmlns:p="http://example.com/ns/p"
              q:b="B900"/>

The following query demonstrates that when a namespace binding is not used to generate a query result, the namespace binding is not added to the in-scope namespaces of a constructed element.

SELECT XMLQUERY(
  'declare namespace p="http://example.com/ns/p";
  <newdoc>
    { $d/p:element1/p:element2 }
  </newdoc>'
  PASSING XMLPARSE(DOCUMENT 
  '<p2:element1 xmlns:p2="http://example.com/ns/p">
     <p2:element2>New element</p2:element2>
   </p2:element1>')
  as "d")
FROM SYSIBM.SYSDUMMY1

The namespace binding p="http://example.com/ns/p" is not added to the in-scope namespaces of p:element2, even though p appears in the query.

The query returns the following result:

<newdoc>
  <p2:element2 xmlns:p2="http://example.com/ns/p">
    New element
  </p2:element2>
</newdoc>