2015-05-23 38 views
2

我使用XQuery处理器撒克逊人,现在我们写的Xquery在“.xqy”文件,其中我们指上,我们将执行Xquery.please看到例如XML文件如下─如何动态地指一个XML文件XQuery中撒克逊

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

现在我想使用没有存储在一些path.Say比如我想引用下面的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)); 
     } 
    }  
} 

`

+0

你可以将字符串作为参数,并解析它的XQuery代码里面'解析的XML($ PARAM)'或者你可以解析Java中的XML并将其作为参数传递给您的XQuery代码。你可以使用撒克逊向我们展示你的Java代码吗?您使用撒克逊的哪些API? –

+0

@MartinHonnen感谢评论。我已经添加了java代码,请参阅上文。 –

回答

2

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

这里是如何实例撒克逊,编译查询,分析输入和评估与约束为上下文项的输入文档的查询:

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

+0

** **的XQuery与命名空间[使用s9api用于XQuery的](http://www.saxonica.com/documentation9.5/index.html#!using-xquery/api-query/s9api-query )'编译器。 declareNamespace(“soap”,“http://schemas.xmlsoap.org/soap/envelope/");compiler.compile("for $ x in/soap:Envelope return $ x/soap:Body”);'[Saxon -HE - *罐子(http://mvnrepository.com/artifact/net.sf.saxon/Saxon-HE ) – Yash

0

这里是我是如何实现由以上所建议的用户自

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

我不知道你如何创建'input'真实的,但我建议你看一下在[DocumentBuilder.newBuildingStreamWriter](http://www.saxonica.com/html/documentation/javadoc/net/sf/saxon/s9api/DocumentBuilder.html#newBuildingStreamWriter%28%29)一种方法来直接构造树,以编程方式,而不是生成要解析的字符串。 –

+0

@FlorentGeorges但为什么我需要锁?我从webservice获取这个xml数据,然后我正在读取某些特定的元素。在这种情况下,我需要锁吗? –

+0

嗯,不知道你的意思是“* lock *”。如果您将文档作为字符串检索,那么您必须解析它。但是从你的问题来看,这并不清楚,如果你自己创建了字符串(比如使用concats和stuff),那么通常这是一个糟糕的主意。 –