如何使用xquery在java

时间:2017-06-19 19:22:41

标签: java xml xquery

我正在使用xquery来查询大型xml文档。使用xquery doc函数不会导致内存堆出站? 如何在java中使用xquery来查询大型xml文件。 将举例说明。

2 个答案:

答案 0 :(得分:1)

考虑到今天的机器有多强大,首先150 MB并不是那么大。如果它增长到GB,则考虑使用Stax或SAX。

XPath / Xquery资源的使用将取决于实现,例如,对于Dom4J,与DOM相比,XPath / Xquery通常显着减少了资源,但这通常取决于各种其他因素,如文档的长度(即您拥有多少个childNode'元素)以及您感兴趣的数据文档中的位置。

引自https://stackoverflow.com/a/725007/6785908

  

XPath内存使用和完成时间往往会进一步增加   你去的文件。例如,假设你有一个XML   文件有20,000个childNode元素,每个childNode都有一个唯一的   您事先知道的标识符,并且您想要提取已知的标识符   来自文档的childNode。提取18,345个childNode会   使用比提取第三个更多,更多,更多的内存。

     

因此,如果您使用XPath来提取所有childNode元素,那么您可以   发现它比解析成DOM效率低。 XPath通常是一个   提取XML doucment的一部分的简单方法。我不推荐   用它来处理所有的XML文档。

Spring Xquery示例

https://github.com/spring-projects/spring-integration-extensions/tree/master/samples/xquery

使用Java的Xquery示例

这是我从第一个谷歌搜索结果https://docs.oracle.com/database/121/ADXDK/adx_j_xqj.htm#ADXDK115

获得的
import javax.xml.xquery.XQConnection;
import javax.xml.xquery.XQException;
import javax.xml.xquery.XQPreparedExpression;
import javax.xml.xquery.XQSequence;

import oracle.xml.xquery.OXQDataSource;

public class HelloWorld {

    public static void main(String[] args) throws XQException {
        OXQDataSource ds = new OXQDataSource();
        XQConnection con = ds.getConnection();
        String query = "<hello-world>{1 + 1}</hello-world>";
        XQPreparedExpression expr = con.prepareExpression(query);
        XQSequence result = expr.executeQuery();

        // prints "<hello-world>2</hello-world>"
        System.out.println(result.getSequenceAsString(null));

        result.close();
        expr.close();
        con.close();
    }

} 

我想重申一下,对于150 MB大小的xml处理,你不必过分担心内存占用。

答案 1 :(得分:0)

150Mb现在不是很大,一个不错的XQuery处理器应该能够在内存中处理它。在不知道您打算使用什么XQuery处理器的情况下,很难给出这个问题的一般答案。

除此之外,它非常依赖于查询正在做什么(你没有告诉我们)。

对于连接查询,获得可接受的性能将取决于XQuery处理器中的优化器有多好。

一些查询将从一种称为“文档投影”的技术中受益匪浅,该技术分析查询以确定需要文档的哪些部分,并避免将内存分配给未被查询访问的树的那些部分。检查您的XQuery处理器是否支持此技术。 (例如,Saxon确实如此,但仅限于Saxon-EE,并且它不是默认值。)

此外,某些查询可能是可流式的,这意味着根本不需要在内存中构建树。再次,检查您选择的XQuery处理器是否支持流式传输。 Saxon确实 - 仅在Saxon-EE中,你必须在命令行中使用一个选项来请求它。