0
votes

I'm using Basex 8.0 beta on ubuntu 14.04

My database contains XML documents with elements that look like this

<messages>
  <message>      
    <message-time-stamp>
      <date>20141004</date>
      <time>193843</time>
      <utc-offset>-0400</utc-offset>
    </message-time-stamp>
  </message>
</messages>

I can use the following xquery in the BaseX gui to update all message-time-stamp nodes with a concatenated timestamp

declare variable $data := db:open('testdb');

  (: Find all elements with time and return the parent element :)
  for $n in $data//../time/..
  return (
    if (exists($n/utc-time-stamp)) then ()
   else insert node 
     <utc-time-stamp>
     {fn:concat (
        fn:substring($n/date, 1, 4),"-",
        fn:substring($n/date, 5, 2),"-",
        fn:substring($n/date, 7, 2),"T",
        fn:substring($n/time, 1, 2),":",
        fn:substring($n/time, 3, 2),":",
        fn:substring($n/time, 5, 2),
        fn:substring($n/utc-offset, 1, 3),
        fn:substring($n/utc-offset, 4, 2))}
     </utc-time-stamp> into $n
)

I embedded the query in a basex script test_bxs.xqy as follows:

<commands>
  <xquery>
  declare variable $data := db:open('testdb');
  (: Find all elements with time and return the parent element :)
  for $n in $data//../time/..
  return (
    if (exists($n/utc-time-stamp)) then ()
    else insert node 
     <utc-time-stamp>
     {fn:concat (
        fn:substring($n/date, 1, 4),"-",
        fn:substring($n/date, 5, 2),"-",
        fn:substring($n/date, 7, 2),"T",
        fn:substring($n/time, 1, 2),":",
        fn:substring($n/time, 3, 2),":",
        fn:substring($n/time, 5, 2),
        fn:substring($n/utc-offset, 1, 3),
        fn:substring($n/utc-offset, 4, 2))}
     </utc-time-stamp> into $n 
  )
  </xquery>
</commands>

And execute as follows:

$ basex -d -c test_bxs.xqy
org.basex.query.QueryException: Syntax: <xquery>[query]</xquery>
        at org.basex.core.parse.XMLParser.error(XMLParser.java:323)
        at org.basex.core.parse.XMLParser.check(XMLParser.java:313)
        at org.basex.core.parse.XMLParser.command(XMLParser.java:167)
        at org.basex.core.parse.XMLParser.parse(XMLParser.java:47)
        at org.basex.core.parse.CmdParser.parse(CmdParser.java:57)
        at org.basex.core.parse.CommandParser.parse(CommandParser.java:75)
        at org.basex.core.parse.CommandParser.parse(CommandParser.java:54)
        at org.basex.core.CLI.execute(CLI.java:88)
        at org.basex.core.CLI.execute(CLI.java:77)
        at org.basex.BaseX.<init>(BaseX.java:85)
        at org.basex.BaseX.main(BaseX.java:42)
org.basex.core.BaseXException: Syntax: <xquery>[query]</xquery>
        at org.basex.core.CLI.execute(CLI.java:93)
        at org.basex.core.CLI.execute(CLI.java:77)
        at org.basex.BaseX.<init>(BaseX.java:85)
        at org.basex.BaseX.main(BaseX.java:42)
Caused by: org.basex.query.QueryException: Syntax: <xquery>[query]</xquery>
        at org.basex.core.parse.XMLParser.error(XMLParser.java:323)
        at org.basex.core.parse.XMLParser.check(XMLParser.java:313)
        at org.basex.core.parse.XMLParser.command(XMLParser.java:167)
        at org.basex.core.parse.XMLParser.parse(XMLParser.java:47)
        at org.basex.core.parse.CmdParser.parse(CmdParser.java:57)
        at org.basex.core.parse.CommandParser.parse(CommandParser.java:75)
        at org.basex.core.parse.CommandParser.parse(CommandParser.java:54)
        at org.basex.core.CLI.execute(CLI.java:88)
        ... 3 more
Syntax: <xquery>[query]</xquery>

If I remove the insert statement and insert a db:output("."), the script runs fine from the command line, but of course does not update the database.

<commands>
  <xquery>
  declare variable $data := db:open('testdb');
  (: Find all elements with time and return the parent element :)
  for $n in $data//../time/..
  return (
    if (exists($n/utc-time-stamp)) then (db:output("."))
    else (db:output("."))
  )
  </xquery>
</commands>

Since the script performs as expected in the GUI, I would expect similar results when using from the command line.

Any help would be appreciated

Thanks in advance

1

1 Answers

1
votes

BaseX command scripts should always have a file ending of .bxs as outlined in the documentation.

The reason your approach fails is that in an XML command script you can not use XML elements, as the scripting language itself consists of XML elements. However, as it seems you only want to execute your xquery file, so simply store the XQuery itself (i.e. without surrounding commands and xquery elements) in a file and run it with

basex test_bxs.xqy

assuming your overwrite your existing file.