关于Java:如何在Saxon中的XQuery中动态引用XML文件

Howto refer dynamically to an XML file in XQuery in Saxon

我正在使用XQuery处理器Saxon。
现在,我们将XQuery写入" .xqy"文件中,在该文件中引用将在其上执行XQuery的XML文件。
请参见以下示例:

1
2
3
for $x in doc("books.xml")/books/book
where $x/price>30
return $x/title

现在,我想使用未存储在某些路径中的动态生成的XML。 举例来说,我想在下面引用可作为字符串使用的XML。

怎么做?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
String book=
<books>
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours
      Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours
      Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours
      Robert</author>
      Peter</author>
      <year>2013</year>
      <price>50.00</price>
   </book>
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours
      Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
</books>

Java代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;

import com.saxonica.xqj.SaxonXQDataSource;

public class XQueryTester {
   public static void main(String[] args){
      try {
         execute();
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (XQException e) {
         e.printStackTrace();
      }
   }

   private static void execute() throws FileNotFoundException, XQException{
      InputStream inputStream = new FileInputStream(new File("books.xqy"));
      XQDataSource ds = new SaxonXQDataSource();
      XQConnection conn = ds.getConnection();
      XQPreparedExpression exp = conn.prepareExpression(inputStream);
      XQResultSequence result = exp.executeQuery();
      while (result.next()) {
         System.out.println(result.getItemAsString(null));
      }
   }    
}


如果您正在寻找一种使用Java绑定查询输入(上下文项)的方法,我建议您使用Saxon的S9API(Java中XSLT,XPath和XQuery处理的最直观的API)。

这是实例化Saxon,编译查询,解析输入并以绑定到其上下文项的输入文档评估查询的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// the Saxon processor object
Processor saxon = new Processor(false);

// compile the query
XQueryCompiler compiler = saxon.newXQueryCompiler();
XQueryExecutable exec = compiler.compile(new File("yours.xqy"));

// parse the string as a document node
DocumentBuilder builder = saxon.newDocumentBuilder();
String input ="<xml>...</xml>";
Source src = new StreamSource(new StringReader(input));
XdmNode doc = builder.build(src);

// instantiate the query, bind the input and evaluate
XQueryEvaluator query = exec.load();
query.setContextItem(doc);
XdmValue result = query.evaluate();

请注意,如果Java代码正在生成XML文档,我强烈建议您使用S9API直接在内存中构建树,而不是将XML文档生成为字符串,然后对其进行解析。 如果可能的话。


这是我根据上述用户的建议实施的方式-

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;

import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQDataSource;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQResultSequence;

import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XQueryCompiler;
import net.sf.saxon.s9api.XQueryEvaluator;
import net.sf.saxon.s9api.XQueryExecutable;
import net.sf.saxon.s9api.XdmNode;
import net.sf.saxon.s9api.XdmValue;

import com.saxonica.xqj.SaxonXQDataSource;


public class Xml {  public static void main(String[] args){
    try {
        process();
     } catch (FileNotFoundException e) {
        e.printStackTrace();
     } catch (Exception e) {
        e.printStackTrace();
     }
  }
public static void process() throws SaxonApiException, IOException{
    // the Saxon processor object
    Processor saxon = new Processor(false);

    // compile the query
    XQueryCompiler compiler = saxon.newXQueryCompiler();
    XQueryExecutable exec;
    exec = compiler.compile(new File("E:\\\\abc.xqy"));


    // parse the string as a document node
    DocumentBuilder builder = saxon.newDocumentBuilder();
    String input ="<data><name>A</name>"
        +"Manager</employee>+<name>B</name>"
        +"Manager</employee>+</data>";
    Source src = new StreamSource(new StringReader(input));
    XdmNode doc = builder.build(src);

    // instantiate the query, bind the input and evaluate
    XQueryEvaluator query = exec.load();
    query.setContextItem(doc);
    XdmValue result = query.evaluate();
    System.out.println(result.itemAt(0));
}