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