Your example 2 does the job, thank you! Although I had to change the
second-to-last line from
return file:write('data/'|| $page/@key || '.xml', $page,
to
return file:write('data/'|| $page/@key || '.xml', $new-part,
One last thing: if I want to specify the path to the input file on the
command line, how do I then refer to it in the script? From the
Command-Line Options page, it seems I can say
-i/my/path/to/input.xml
But what do I use in place of $input in that case? If I just remove
"$input" from the script I get a "no context value bound" error if I say
-i/my/path/to/input.xml
or
-i/my/path/to/input.xml "/"
Thanks,
Michael
On Thu, May 26, 2016 at 11:21 PM, Christian Grün <[email protected]>
wrote:
> Hi Michael,
>
> > 1) There'll be a new version of the input file arriving periodically, so
> I'd
> > prefer to be able to do everything at the command line without having to
> > create the database inside the GUI. Not sure of the best way to go about
> > that.
>
> Using the GUI was just an example. You can create new databases via
> commands (CREATE), XQuery (db:create) or our APIs. Please check out
> our documentation for more hints.
>
> > 2) In the GUI for now, I can perform the replace with the map, or I can
> run
> > the for loop that writes out all the files. But I get an "Unexpected end
> of
> > query" error when I try to do both, so what's the problem with my syntax?
>
> In XQuery, multiple expressions can be separated with commas.
>
> Note, however, that XQuery is a functional language; as such, it is
> not possible to first update items and then access them in the same
> query that easily. There are various alternatives to get around this
> limitation:
>
> 1. Use a BaseX command script to run all operations [1]:
>
> <commands>
> <create-db name='input'>...path/to/input.xml</create-db>
> <xquery><![CDATA[
> let $map := ...
> ]]></xquery>
> <xquery>
> for $page in ...
> <xquery>
> </commands>
>
> 2. Use copy/transform/return or update to do all updates in
> main-memory [2] and pass them on to your file:write function. This
> could e.g. look as follows:
>
> let $input := doc('input.xml')
> let $map := map:merge(
> for $part in $input//part
> return map:entry(string-join($part/partinfo/*, '/'), $part)
> )
> for $page in $input//page
> let $new-part := $page update {
> for $partinfo in .//unit/partinfo
> let $part := $map(string-join($partinfo/*, '/'))
> return replace node $partinfo with element part { $part/node() }
> }
> return file:write('data/'|| $page/@key || '.xml', $page,
> map{ "omit-xml-declaration": "no" })
>
> The good thing here is that your replace operations won’t need to be
> cached until the very end; they will directly be run on each page
> element (and not persisted on disk; but this is something you don’t
> need anyway it seems)
>
> Christian
>
> [1] http://docs.basex.org/wiki/Commands#Command_Scripts
> [2] http://docs.basex.org/wiki/XQuery_Update#Non-Updating_Expressions
>