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
GerritQuoted 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
Written for BaseX 7.8. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery