6

我正在使用 XQuery 处理器 Saxon。
现在我们将 XQuery 写入一个“.xqy”文件,在该文件中我们引用了我们将在其上执行 XQuery 的 XML 文件。
请看下面的例子:

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

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

怎么做?

String book=
<books>
   <book category="JAVA">
      <title lang="en">Learn Java in 24 Hours</title>
      <author>Robert</author>
      <year>2005</year>
      <price>30.00</price>
   </book>
   <book category="DOTNET">
      <title lang="en">Learn .Net in 24 hours</title>
      <author>Peter</author>
      <year>2011</year>
      <price>40.50</price>
   </book>
   <book category="XML">
      <title lang="en">Learn XQuery in 24 hours</title>
      <author>Robert</author>
      <author>Peter</author> 
      <year>2013</year>
      <price>50.00</price>
   </book>
   <book category="XML">
      <title lang="en">Learn XPath in 24 hours</title>
      <author>Jay Ban</author>
      <year>2010</year>
      <price>16.50</price>
   </book>
</books>

Java代码:

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));
      }
   }    
}
4

2 回答 2

5

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

以下是如何实例化 Saxon、编译查询、解析输入和评估查询,并将输入文档绑定为其上下文项:

// 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 文档生成为字符串,然后对其进行解析。如果可能的话。

于 2015-05-23T17:23:27.137 回答
1

这是我按照上述用户的建议实施的方式-

    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><employee id=\"1\"><name>A</name>"
        + "<title>Manager</title></employee>+<employee id=\"2\"><name>B</name>"
        + "<title>Manager</title></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));
}
于 2015-05-23T18:07:01.587 回答