3

I am trying to use the Java BaseX XQJ API to insert data into a XML-file.

The code is as follows (imports are ommited):

public class BaseXTest {
public static void main(String[] args) throws Exception {

    // obtain an XQDataSource instance
    XQDataSource ds = new BaseXXQDataSource();
    ds.setProperty("serverName", "localhost");
    ds.setProperty("port", "1984");
    ds.setProperty("user", "admin");
    ds.setProperty("password", "admin");

    XQConnection xqc = ds.getConnection();
    XQExpression xqe = xqc.createExpression();
    xqe.executeCommand("CREATE DB myTestDB");
    ds.setProperty("databaseName", "myTestDB");

    File myTestDbDataFile = new File("PATH_TO_MY_XML_FILE");
    XQConnection2 xqc2 = (XQConnection2) ds.getConnection();
    XQItem xqItem = xqc2.createItemFromDocument(new FileInputStream(myTestDbDataFile), null, null);
    xqc2.insertItem(myTestDbDataFile.getName(), xqItem, null);

            //this query works
    // XQResultSequence rs = xqe
    // .executeQuery("for $i in (1 to 10) return $i");

            //this query works too
    // XQResultSequence rs =
    // xqe.executeQuery("doc('PATH_TO_MY_XML_FILE')/myTestDbRootNode");

            //this query works NOT
    XQResultSequence rs = xqe.executeQuery("insert node 'abcdefg' into doc('PATH_TO_MY_XML_FILE')/myTestDbRootNode");
    rs.writeSequence(System.out, null);

    xqc.close();

}
}

The above code throws this exception (in line with the statement 'rs.writeSequence(System.out, null);'):

Exception in thread "main" javax.xml.xquery.XQException:
 XQJFOS021 - FORWARD_ONLY_SEQUENCE: Cursor is not positioned on an XQItem.
 at XmlTestMain.main(XmlTestMain.java:118)


Why is this the case and how can i issue a working "insert"-directive to the database?

I guess there is something wrong with the usage of the "executeQuery()-method" in case of an insert, since it can process the other two directives issued.

kiltek
  • 3,183
  • 6
  • 47
  • 70

1 Answers1

2

I guess the query is actually working. However, what return value do you actually expect?

The XQuery Update statement you execute does not return any result (see https://docs.basex.org/wiki/Updates#Returning_Results for more information), thus the result is not an XQItem.

Also, if you want to modify main-memory nodes (like reading them using fn:doc) you might want to turn the WRITEBACK option on. If you actually want to transform the document and return the result back to you application, you might want to use the transform expression.

dirkk
  • 6,160
  • 5
  • 33
  • 51
  • I expected that when opening the xml-file of that database in a Text-Editor the inserts would appear. I didn't expect any special return values. What can i do to make that happen? – kiltek Nov 24 '13 at 17:45
  • I think you are confusing documents resisting within the file systems with documents within a database. If you put documents in a database, they are stored in a specific storage format (to allow faster access and querying), not in plain text. The document is then independent from the original input document. However, you can use the writeback option to propagate changes to the original document. Or you can write data to disk by using `fn:put` or `file:write`(see https://docs.basex.org/wiki/File_Module#file:write). – dirkk Nov 25 '13 at 09:22
  • Thanks, i have tried the following: `XQResultSequence rs = xqe.executeQuery("WRITEBACK true");` AND `xqe.executeCommand("WRITEBACK true");` AND `ds.setProperty("writeback", "true");`. They dont work. How can I set the WRITEBACK option through java. – kiltek Nov 25 '13 at 12:38
  • 1
    I used `xqe.executeCommand("SET WRITEBACK true");` and it worked. – kiltek Nov 25 '13 at 12:54