XQuery Update and Namespace Manipulation

Monday, 9 September 2019 · 8 messages · last reply 14 Sep 2019
AM
Andreas Mixich9 Sep 2019 20:30 #
Hi,
copy $c := <lorem>ipsum dolor sit amet</lorem>
modify insert node namespace {"lipsum"} {"lorem-ipsum"} into $c
return $c
Expected result:
<lipsum:lorem xmlns:lipsum="lorem-ipsum">ipsum dolor sit amet</lipsum:lorem>
but I get
<lorem>ipsum dolor sit amet</lorem>

copy $c := <lorem>ipsum dolor sit amet</lorem>
modify replace node $c/namespace-node() with namespace {"lipsum"}
{"lorem-ipsum"}
return $c
Here I get an error: [XQST0134] Namespace axis is not supported. How can I change namespaces for nodes with the simple update expressions? For background: I try to implement a function:
declare function local:add-namespaces-to-nodes(
  $nodes as element()*,
  $namespaces as array(*)*)
  as element()*
{
  for $namespace in $namespaces
  for $node in $nodes
  return copy $c := $node
         modify insert node (namespace {$namespace(1)} {$namespace(2)})
into $c
         return $c
};
Thanks!
-- Minden jót, all the best, Alles Gute, Andreas Mixich
MH
Martin Honnen9 Sep 2019 20:35 #
Quoted text · Andreas Mixich · 10 lines
On 09.09.2019 20:30, Andreas Mixich wrote: > Hi, > > copy $c := <lorem>ipsum dolor sit amet</lorem> > modify insert node namespace {"lipsum"} {"lorem-ipsum"} into $c > return $c > > Expected result: > > <lipsum:lorem xmlns:lipsum="lorem-ipsum">ipsum dolor sit amet</lipsum:lorem>
The namespace is part of the name of a node so you need to rename the node(s) in a namespace if you want to change the namespace, see https://www.w3.org/TR/xquery-update/#id-rename saying The effects of a rename expression are limited to its target node. Attributes and descendants of the target node are not affected. If a global change of names or namespaces is intended, some form of explicit iteration must be used. The following example illustrates such a global change. The example operates on the node bound to variable $root and all its attributes and descendants, changing all QNames with the prefix abc to have a new prefix xyz and a new namespace URI http://xyz/ns.
for $node in $root//abc:*
let $localName := fn:local-name($node),
     $newQName := fn:concat("xyz:", $localName)
return (
    rename node $node as fn:QName("http://xyz/ns", $newQName),
    for $attr in $node/@abc:*
    let $attrLocalName := fn:local-name($attr),
        $attrNewQName := fn:concat("xyz:", $attrLocalName)
    return
       rename node $attr as fn:QName("http://xyz/ns", $attrNewQName)
)
MH
Martin Honnen9 Sep 2019 22:41 #
Quoted text · Andreas Mixich · 16 lines
On 09.09.2019 20:35, Martin Honnen wrote: > On 09.09.2019 20:30, Andreas Mixich wrote: >> Hi, >> >> copy $c := <lorem>ipsum dolor sit amet</lorem> >> modify insert node namespace {"lipsum"} {"lorem-ipsum"} into $c >> return $c >> >> Expected result: >> >> <lipsum:lorem xmlns:lipsum="lorem-ipsum">ipsum dolor sit >> amet</lipsum:lorem> > > > The namespace is part of the name of a node so you need to rename the > node(s) in a namespace if you want to change the namespace
Your example would be
copy $c := <lorem>ipsum dolor sit amet</lorem>
modify rename node $c as QName("lorem-ipsum", "lipsum:" || local-name($c))
return $c
AM
Andreas Mixich10 Sep 2019 03:03 #
Thanks a lot! So it seems, I must give the node a new identity instead of just modifying the old identity.
Quoted text · Martin Honnen · 26 lines
On Mon, Sep 9, 2019 at 10:41 PM Martin Honnen <martin.honnen at gmx.de> wrote: > On 09.09.2019 20:35, Martin Honnen wrote: > > On 09.09.2019 20:30, Andreas Mixich wrote: > >> Hi, > >> > >> copy $c := <lorem>ipsum dolor sit amet</lorem> > >> modify insert node namespace {"lipsum"} {"lorem-ipsum"} into $c > >> return $c > >> > >> Expected result: > >> > >> <lipsum:lorem xmlns:lipsum="lorem-ipsum">ipsum dolor sit > >> amet</lipsum:lorem> > > > > > > The namespace is part of the name of a node so you need to rename the > > node(s) in a namespace if you want to change the namespace > > Your example would be > > copy $c := <lorem>ipsum dolor sit amet</lorem> > modify rename node $c as QName("lorem-ipsum", "lipsum:" || local-name($c)) > return $c > > >
-- Minden jót, all the best, Alles Gute, Andreas Mixich
AM
Andreas Mixich10 Sep 2019 03:50 #
adding to my last email: of course, this way I still did not solve addition of more namespaces. Any ideas on that? modify insert node namespace {"foo"} {"foobar"} into $c/self::node() Because, even if I reconstruct the node completely, with the non-updating expressions, I would not know any other syntax, that would match the purpose. I know, how to construct nodes with simple expressions, using the element constructors, however I am interested in the 'non-updating updating' (and how to call them differently, lol) expressions.
-- Minden jót, all the best, Alles Gute, Andreas Mixich
MH
Martin Honnen10 Sep 2019 23:35 #
Quoted text · Andreas Mixich · 10 lines
On 10.09.2019 03:50, Andreas Mixich wrote: > > adding to my last email: of course, this way I still did not solve > addition of more namespaces. Any ideas on that? > > modify insert node namespace {"foo"} {"foobar"} into $c/self::node() > > Because, even if I reconstruct the node completely, with the > non-updating expressions, I would not know any other syntax, that would > match the purpose.
Let's hope that Christian or others can give you some insight on that, I can't get any handle on how to figure where/how the XQuery update spec or implementations allow deletion or insertion of namespaces. I found one question on StackOverflow answered by Christian that suggested that deletion is not possible with XQuery update.
CG
Christian Grün11 Sep 2019 10:38 #
Hi Andreas, As Martin stated (thanks!), the official spec provides no way to delete existing namespaces. It not possible either to insert namespaces that won’t be used. Usually, this is not a big deal: If you insert elements with new namespaces, or if you insert child element with namespaces that overwrite namespaces of parent elements, new namespaces will implicitly be added to your XML fragment:
  declare namespace lipsum = 'lorem-ipsum';
  copy $c := <lorem/>
  modify insert node <lipsum:new/> into $c
  return $c
Quoted text · Martin Honnen · 1 line
> So it seems, I must give the node a new identity instead of just modifying the old identity.
Just a side note: Due to the functional nature of the language, it is never possible with XQuery to modify identities. You will always get copies of your original data (that may eventually replace your old data, e.g. in the database). Hope this helps, Christian
Quoted text · Martin Honnen · 19 lines
On Tue, Sep 10, 2019 at 11:35 PM Martin Honnen <martin.honnen at gmx.de> wrote: > > On 10.09.2019 03:50, Andreas Mixich wrote: > > > > adding to my last email: of course, this way I still did not solve > > addition of more namespaces. Any ideas on that? > > > > modify insert node namespace {"foo"} {"foobar"} into $c/self::node() > > > > Because, even if I reconstruct the node completely, with the > > non-updating expressions, I would not know any other syntax, that would > > match the purpose. > > Let's hope that Christian or others can give you some insight on that, I > can't get any handle on how to figure where/how the XQuery update spec > or implementations allow deletion or insertion of namespaces. I found > one question on StackOverflow answered by Christian that suggested that > deletion is not possible with XQuery update. >
AM
Andreas Mixich14 Sep 2019 15:51 #
Hi Martin, Christian, thanks a lot for clarification on this.
Quoted text · Christian Grün · 4 lines
Usually, this is not a big deal: If you insert elements with new > namespaces, or if you insert child element with namespaces that > overwrite namespaces of parent elements, new namespaces will > implicitly be added to your XML fragment:
Doh! That slipped my mind. Facepalm! ;-)
Quoted text · Christian Grün · 2 lines
Just a side note: Due to the functional nature of the language, it is > never possible with XQuery to modify identities.
Right.
Quoted text · Christian Grün · 52 lines
On Wed, Sep 11, 2019 at 10:38 AM Christian Grün <christian.gruen at gmail.com> wrote: > Hi Andreas, > > As Martin stated (thanks!), the official spec provides no way to > delete existing namespaces. It not possible either to insert > namespaces that won’t be used. > > Usually, this is not a big deal: If you insert elements with new > namespaces, or if you insert child element with namespaces that > overwrite namespaces of parent elements, new namespaces will > implicitly be added to your XML fragment: > > declare namespace lipsum = 'lorem-ipsum'; > copy $c := <lorem/> > modify insert node <lipsum:new/> into $c > return $c > > > So it seems, I must give the node a new identity instead of just > modifying the old identity. > > Just a side note: Due to the functional nature of the language, it is > never possible with XQuery to modify identities. You will always get > copies of your original data (that may eventually replace your old > data, e.g. in the database). > > Hope this helps, > Christian > > > > On Tue, Sep 10, 2019 at 11:35 PM Martin Honnen <martin.honnen at gmx.de> > wrote: > > > > On 10.09.2019 03:50, Andreas Mixich wrote: > > > > > > adding to my last email: of course, this way I still did not solve > > > addition of more namespaces. Any ideas on that? > > > > > > modify insert node namespace {"foo"} {"foobar"} into $c/self::node() > > > > > > Because, even if I reconstruct the node completely, with the > > > non-updating expressions, I would not know any other syntax, that would > > > match the purpose. > > > > Let's hope that Christian or others can give you some insight on that, I > > can't get any handle on how to figure where/how the XQuery update spec > > or implementations allow deletion or insertion of namespaces. I found > > one question on StackOverflow answered by Christian that suggested that > > deletion is not possible with XQuery update. > > >
-- Minden jót, all the best, Alles Gute, Andreas Mixich

⚡Generated with XQuery