简体   繁体   中英

How to use XQuery to output json using Saxon from Java

I'm using XQuery to convert the XML document below to JSON, using Saxon to process the XQuery file.

<books>
   <book id="book1">
      <author>Book1AuthorSurname, Book1AuthorFirstname</author>
      <title>Book1 Title</title>
      <price>45.00</price>
   </book>
   <book id="book2">
      <author>Book2AuthorSurname, Book2AuthorFirstname</author>
      <title>Book2 Title</title>
      <price>45.00</price>
   </book>
</books>

The XQuery itself is pretty straightforward

xquery version "3.1";

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization"; 
declare namespace map = "http://www.w3.org/2005/xpath-functions/map";

declare option output:method "json";
declare option output:indent "yes";

let $booksXML := doc("books.xml")/books

return array {
  for $book in $booksXML/book
  return map {
   "author": data($book/author),
   "title": data($book/title)
  }
}

and, if I run it from the command line with Saxon, returns correctly

java -cp Saxon-HE-9.8.0-8.jar net.sf.saxon.Query -q:books2json.xqy

 [
   {
    "author":"Book1AuthorSurname, Book1AuthorFirstname",
    "title":"Book1 Title"
   },
   {
    "author":"Book2AuthorSurname, Book2AuthorFirstname",
    "title":"Book2 Title"
   }
 ]

But running it from Java with the following snippet gives a slightly different result

Processor saxon = new Processor(false);
XQueryCompiler compiler = saxon.newXQueryCompiler();
XQueryExecutable exec = compiler.compile(new File("books2json.xqy"));
XQueryEvaluator query = exec.load();
XdmValue result = query.evaluate();
System.out.println(result.toString());

[
    map{"author":"Book1AuthorSurname, Book1AuthorFirstname","title":"Book1 Title"},
    map{"author":"Book2AuthorSurname, Book2AuthorFirstname","title":"Book2 Title"}
]

The "map" in the output from Java is giving an error in a JSON processor that I'm using to read the results, is there a configuration option to remove this from the result?

If you want to directly write to System.out respectively any other Destination then you can do it using the run method like this:

    Processor saxon = new Processor(false);
    XQueryCompiler compiler = saxon.newXQueryCompiler();
    XQueryExecutable exec = compiler.compile(new File("query1.xq"));
    XQueryEvaluator query = exec.load(); 

    query.run(saxon.newSerializer(System.out));
    System.out.println();

respectively if you want a String use a Serializer over a StringWriter:

    StringWriter sw = new StringWriter();
    query.run(saxon.newSerializer(sw));
    String result = sw.toString();
    System.out.println(result);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM