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
>

Reply via email to