DB2 Version 10.1 for Linux, UNIX, and Windows

Specifying XML namespaces

In an XML document, an XML namespace is optional and is used as a prefix for node names in the XML document. To access the nodes in an XML document that uses a namespace, your XQuery expressions must also specify the same namespace as part of the node name.

A default XML namespace can be specified for a document, and XML namespaces can be specified for specific elements in a document.

Note that namespace declarations are terminated by a semicolon (;). This means that you cannot use the semicolon as a statement termination character if you also want to work with SQL statements and XQuery expressions that contain the semicolon, for example, by invoking the command line processor with db2 -t. You can specify a termination character other than the semicolon with the -td option, which ensures that statements containing namespace declarations are not misinterpreted. The examples in the tutorial use the tilde (~) as the termination character (-td~), but % is also commonly used (-td%).

For example, the tutorial for pureXML® uses XML documents that specify a default element namespace for an XML document. The following XML is one of the XML documents used in the tutorial:

<customerinfo xmlns="http://posample.org" Cid="1002"> 
  <name>Jim Noodle</name> 
  <addr country="Canada"> 
    <street>25 EastCreek</street> 
    <city>Markham</city> 
    <prov-state>Ontario</prov-state> 
    <pcode-zip>N9C 3T6</pcode-zip> 
  </addr> 
  <phone type="work">905-555-7258</phone> 
</customerinfo>

The root node of the XML document binds the default element namespace for the document to the Universal Resource Identifier (URI) http://posample.org.

<customerinfo xmlns="http://posample.org" Cid="1002">

The XQuery expressions you run in the tutorial also bind a URI as the default element namespace by including a declare default element namespace prolog. For example, the XQuery expression in the following SELECT statement declares a default element namespace; if you run the SELECT statement against the CUSTOMER table created in the tutorial, one Customer ID is returned:

SELECT cid FROM customer
   WHERE XMLEXISTS('declare default element namespace "http://posample.org";
   $i/customerinfo/addr/city[ . = "Markham"]' passing INFO as "i")

By using the same URI as the default element namespace in the XML document, the expression qualifies the node names in the expression with the correct namespace prefix. Without a default element namespace declaration, or with a different URI bound as the default element namespace, the expression does not qualify the node names with the correct namespace and no data is returned. For example, the following SELECT statement is similar to the previous statement but does not have a default namespace declaration. If you run this statement against the CUSTOMER table created in the tutorial, no data is returned.

SELECT cid FROM customer
WHERE XMLEXISTS('$i/customerinfo/addr/city[ . = "Markham"]' 
   passing INFO as "i")

Using a namespace prefix with a node name

To qualify a node name with a namespace, you can add the namespace prefix for each node name. You separate the prefix and the node name with a colon. For the node po:addr, the namespace prefix po is separated from the local node name addr. If you qualify a namespace prefix with a node name, you must ensure that the prefix is bound to a URI. For example, the XQuery expression in the following SELECT statement binds the namespace prefix po to the URI http://posample.org by declaring the namespace po. When you run the following statement against the CUSTOMER table created in the tutorial, one result is returned.

SELECT cid FROM customer
WHERE XMLEXISTS('
    declare namespace po = "http://posample.org";
   $i/po:customerinfo/po:addr/po:city[ . = "Markham"]' passing INFO as "i")

The namespace prefix po could be any prefix; what matters is the URI that is bound to the prefix. For example, the XQuery expression in the following SELECT statement uses the namespace prefix mytest but is equivalent to the expression in the previous statement:

SELECT cid FROM customer
WHERE XMLEXISTS('declare namespace mytest = "http://posample.org";
   $i/mytest:customerinfo/mytest:addr/mytest:city[ . = "Markham"]' 
   passing INFO as "i")

Using a wildcard as a namespace prefix

You can use a wildcard character in an XQuery expression to match any namespace used in the XML data. The XQuery expression in the following SELECT statement uses a wildcard character to match all namespace prefixes.

SELECT cid FROM customer
WHERE XMLEXISTS('$i/*:customerinfo/*:addr/*:city[ . = "Markham"]' 
   passing INFO as "i")

When you run the SELECT statement against the CUSTOMER table created in the tutorial, one Customer ID is returned.