Reputation: 253
The following problem can easily be solved with text processing tools and languages, but this is not how it should be done I guess..
What’s the cleanest and cheapest approach to rename namespace prefixes in a large XML document with XQuery (Update)?
Source:
<a:root xmlns:a="http://my.old.url/"/>
<a:sub/>
</a:root>
The result I’d like to get:
<b:root xmlns:b="http://my.old.url/"/>
<b:sub/>
</b:root>
Any ideas?
Upvotes: 1
Views: 2778
Reputation: 4241
In XQuery Update you can use the rename
expression to rename all elements in a given namespace:
declare namespace ns='http://my.old.url/';
for $nd in doc('your-db')//ns:*
return rename node $nd as QName('http://my.old.url/', concat('b:', local-name($nd)))
If you don't want the changes to be permanent, you can wrap the updates in a Transform Expression, too:
declare namespace ns='http://my.old.url/';
copy $doc :=
document{
<a:root xmlns:a="http://my.old.url/">
<a:sub/>
</a:root>
}
modify
for $nd in $doc//ns:*
return rename node $nd as QName('http://my.old.url/', concat('b:', local-name($nd)))
return $doc
Upvotes: 1
Reputation: 11771
This might be easier to do in XSLT, but in XQuery I think you would just essentially do the same thing. Declare the namespace prefix you want, then recursively process the nodes and update the element names to use that prefix.
xquery version "1.0";
declare namespace b="http://my.old.url/";
declare function local:update-ns-prefix($node)
{
typeswitch($node)
case element() return
element { xs:QName(concat('b:',local-name($node))) }
{
$node/@*,
for $n in $node/node()
return local:update-ns-prefix($n)
}
default return $node
};
let $xml :=
<a:root xmlns:a="http://my.old.url/">
<a:sub xmlns:a="http://my.old.url/"/>
</a:root>
return local:update-ns-prefix($xml)
Upvotes: 0