Stefan K.
Stefan K.

Reputation: 7851

XQuery: return to no namespace

Is it possible to return to no namespace by prefix? In other words when a default namespace is set in Xquery, how do I put an element in no namespace or how do I create an element without an namespace?

My problem is I defined a Xquery mapping from a->b, where I now realized, b expect its children to be unqualified. In the mapping, I've set the default namespace to a and always qualified b. If I remove the nsprefix from bs children, as NS is applied. e.g.

This is desired resulting XML:

<myB:StatusEvent xmlns:myB="http://b">
<Action/> <!-- note Action has no, not even an inherited, namespace -->
</myB:StatusEvent>

while this is the typical prefix use throughout my xquery mapping:

declare default element namespace "http://a";
let $elem :=  doc("someinput.xml")/somePathWithoutMyAPrefix
(: note the xpath expressions use the default a namespace :)
return
<myB:StatusEvent>{$elem/someVal}
    <myNN:Action> (: <== how do I create Action **without** a namespace? :)
</myB:StatusEvent>

Upvotes: 0

Views: 2843

Answers (2)

adamretter
adamretter

Reputation: 3517

I would really advise against using declare default element namespace "http://a";. It is quite evil especially if other developers do not notice it in use and spend ages trying to figure out why they get unexpected results.

That being said, some implementations may support using xmlns="" to place an element back into the default default namespace. e.g.

declare default element namespace "http://a";

<a>
    <other xmlns=""/>
</a>

As far as I am aware, this cannot be done by prefix.

Upvotes: 3

Ewout Graswinckel
Ewout Graswinckel

Reputation: 1273

You're declaration to use a default namespace is only for convenience in the query itself. What I think you want to do is really remove the namespace from some element. You can do such a thing with a recursive function like this:

declare function local:remove-namespace ($node as node()) {
  typeswitch ($node)
    case element() 
      return  element { local-name($node) } {$node/@*, for $child in $node/node() return local:remove-namespace($child) }
    default 
  return $node
};

Just call this methods on the elements where you don't want a namespace (which is not completely clear from your example).

Upvotes: 2

Related Questions