Example: Changing the namespace prefix of an element
These examples demonstrate how add and remove the namespace binding assigned to the QName of an element.
A QName of an element is the optional namespace prefix and the local name. The namespace prefix and the local name are separated by a colon. The namespace prefix, if present, is bound to a URI (Universal Resource Identifier) and provides a shortened form of the URI. The expanded QName includes the namespace URI and a local name.
Using functions such as fn:QName, fn:local-name, and fn:namespace-uri you can rename attribute and node names, and find the URI associated with a node's namespace prefix.
An XQuery namespace declaration is terminated by a semicolon (;). You cannot use the semicolon as a statement termination character. The examples use the tilde (~) as the termination character, which is the same termination character used by the pureXML® tutorial.
Adding a namespace prefix to an element
CREATE TABLE XMLTEST (ID BIGINT NOT NULL PRIMARY KEY, XMLDOC XML ) ~
INSERT INTO XMLTEST Values (4,
'<depts>
<dept id="A07">
<emp id="31201" >
<location region="31" />
</emp>
<emp type="new" id = "23322" >
<moved:location xmlns:moved="http://oldcompany.com" region="43" />
</emp>
</dept>
</depts> ') ~
The XQuery expression in the following SELECT statement adds a namespace prefix to an element. The XQuery expression uses fn:QName to create a QName with a namespace binding.
The XQuery let clause
creates an empty element with name emp
and namespace http://example.com/new
.
In the transform expression, the rename expression
changes the name of the element identified by the XPath expression$newdept/depts/dept/emp[@type="new"]
.
The element is named emp
but has no namespace prefix.
SELECT XMLQUERY ( '
let $newemp := fn:QName( "http://mycompany.com", "new:emp")
return
transform
copy $newdept := $doc
modify
do rename $newdept/depts/dept/emp[@type="new"] as $newemp
return
$newdept ' passing XMLDOC as "doc" )
from XMLTEST where ID = 4 ~
The XQuery expression returns the following XML data
with the namespace binding specified as part of the node new:emp
.
The modified document is valid XML that includes namespace prefixes
that are bound to a namespace. A namespace declaration is added to
the newly renamed element.
<depts>
<dept id="A07">
<emp id="31201">
<location region="31" />
</emp>
<new:emp xmlns:new="http://mycompany.com" type="new" id="23322">
<moved:location xmlns:moved="http://oldcompany.com" region="43" />
</new:emp>
</dept>
</depts>
Removing a namespace prefix from an element
You
can remove a namespace prefix from a node name by renaming the node
to a QName without a namespace binding. The following XQuery expression
in the SELECT statement uses a for clause and the fn:namespace-uri function
to determine the URI of the element nodes within each emp node. If
the URI is http://oldcompany.com
the rename expression
uses the fn:QName and fn:local-name functions
to remove the namespace prefix from the element node.
SELECT XMLQUERY ( '
transform
copy $newdept := $x
modify
for $testemp in $newdept/depts/dept/*:emp/*
return
if ( fn:namespace-uri( $testemp ) eq "http://oldcompany.com")
then
do rename $testemp as fn:QName( "", fn:local-name($testemp) )
else()
return
$newdept
' passing XMLDOC as "x" )
from XMLTEST where ID = 4 ~
The XQuery expression returns
the following XML data. The node name new:location
is
replaced with location
. The namespace binding is
not removed from the node.
<depts>
<dept id="A07">
<emp id="31201">
<location region="31" />
</emp>
<emp type="new" id="23322">
<location xmlns:moved="http://oldcompany.com" region="43" />
</emp>
</dept>
</depts>