transform before update query

Sunday, 16 February 2014 · 3 messages
IL
Imsieke, Gerrit, le-tex16 Feb 2014 15:34 #
This XQuery update related question might be not the most BaseX-specific question that has ever been asked on the list, but anyway: I’m currently improving the performance of sxedit (that I presented at XML Prague yesterday). One nasty workaround that I have to do in the browser is escaping the names of the TEI elements body and head when I generate TEI XML from HTML despite the fact that these elemens are in a different namespace (because browsers…). So I have TEI XML with the elements _____head and _____body. I serialize this XML and use regex replacement on the string when I submit the TEI XML for download or for storage in BaseX. (Yes, it seems silly to serialize the XML before POSTing it to RESTXQ and then using parse-xml(), but don’t mind that for the moment.) The function that does the storage is at https://github.com/gimsieke/sxedit/blob/master/lib/basex/restxq/sxedit.xqm#L221 Now I thought that I might do without the performance-killing string replacement in the browser if I let BaseX transform the posted data prior to replacing the stored subtree with what was posted. So I tried the following for the function body:
     copy $doc := parse-xml($wrapper)
     modify (
       for $n in $doc/descendant-or-self::*[starts-with(local-name(),
'_____')]
       let $repl := replace(local-name($n), '^_____', ''),
           $uri := namespace-uri($n)
       return rename node $n as QName($uri, $repl)
     )
     return
     replace node db:open($doc/*:frag/@db, $doc/*:frag/@doc)//*[path()
eq $doc/*:frag/@xpath]
     with $doc/*:frag/*
upon which I get: [XUST0001] Transform expression: no updating expression allowed. How would I achieve the transform and then update operation? Gerrit
CG
Christian Grün16 Feb 2014 15:40 #
Hi Gerrit, the return clause of the transform (copy) expression does not allow update operations. What you can do is to wrap your code in a FLWOR expression:
let $doc :=
  copy $doc := parse-xml($wrapper)
    modify (
      for $n in $doc/descendant-or-self::*[starts-with(local-name(), '_____')]
      let $repl := replace(local-name($n), '^_____', ''),
          $uri := namespace-uri($n)
      return rename node $n as QName($uri, $repl)
    )
    return $doc
return
    replace node db:open($doc/*:frag/@db, $doc/*:frag/@doc)//*[path()
eq $doc/*:frag/@xpath]
    with $doc/*:frag/*
You can also use the (for now BaseX-specific) "update" keyword, e. g. as follows:
let $doc := parse-xml($wrapper) update (
  for $n in descendant-or-self::*[starts-with(local-name(), '_____')]
  let $repl := replace(local-name($n), '^_____', ''),
      $uri := namespace-uri($n)
  return rename node $n as QName($uri, $repl)
)
return
    replace node db:open($doc/*:frag/@db, $doc/*:frag/@doc)//*[path()
eq $doc/*:frag/@xpath]
    with $doc/*:frag/*
Hope this helps, Christian
IL
Imsieke, Gerrit, le-tex16 Feb 2014 21:52 #
Christian, thanks for your XQuery support. Will pay back in XSLT support ;) I made this change, and I also made the xquery:eval statements compatible with 7.8: https://github.com/gimsieke/sxedit/blob/master/lib/basex/restxq/sxedit.xqm Gerrit
Quoted text · Christian Grün · 39 lines
On 16.02.2014 15:40, Christian Grün wrote: > Hi Gerrit, > > the return clause of the transform (copy) expression does not allow > update operations. What you can do is to wrap your code in a FLWOR > expression: > > let $doc := > copy $doc := parse-xml($wrapper) > modify ( > for $n in $doc/descendant-or-self::*[starts-with(local-name(), '_____')] > let $repl := replace(local-name($n), '^_____', ''), > $uri := namespace-uri($n) > return rename node $n as QName($uri, $repl) > ) > return $doc > return > replace node db:open($doc/*:frag/@db, $doc/*:frag/@doc)//*[path() > eq $doc/*:frag/@xpath] > with $doc/*:frag/* > > > You can also use the (for now BaseX-specific) "update" keyword, e. g. > as follows: > > let $doc := parse-xml($wrapper) update ( > for $n in descendant-or-self::*[starts-with(local-name(), '_____')] > let $repl := replace(local-name($n), '^_____', ''), > $uri := namespace-uri($n) > return rename node $n as QName($uri, $repl) > ) > return > replace node db:open($doc/*:frag/@db, $doc/*:frag/@doc)//*[path() > eq $doc/*:frag/@xpath] > with $doc/*:frag/* > > Hope this helps, > Christian >
-- Gerrit Imsieke Geschäftsführer / Managing Director le-tex publishing services GmbH Weissenfelser Str. 84, 04229 Leipzig, Germany Phone +49 341 355356 110, Fax +49 341 355356 510 gerrit.imsieke at le-tex.de, http://www.le-tex.de Registergericht / Commercial Register: Amtsgericht Leipzig Registernummer / Registration Number: HRB 24930 Geschäftsführer: Gerrit Imsieke, Svea Jelonek, Thomas Schmidt, Dr. Reinhard Vöckler

⚡Generated with XQuery