【问题标题】:How to use xquery to process very large xml file like 150mb in java如何在java中使用xquery处理非常大的xml文件,如150mb
【发布时间】:2017-06-19 19:22:40
【问题描述】:

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

【问题讨论】:

  • 大型 XML 文件不适合 XQuery。更好的选择是通过 SAX 解析器流式传输 XML 文件,以选择性地搜索对象。性能方面,使用 SAX 可以在几秒钟内导航和更新一个 300MB 的文件。
  • 如果查询足够简单,可以使用 SAX 处理,那么它可能适合使用流式 XQuery 处理器进行处理,这将同样快,因为性能主要由 XML 解析决定。好处是 XQuery 解决方案将是 3 行代码,而不是 SAX 解决方案的 300 行代码。

标签: java xml xquery


【解决方案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 个子节点将 使用比提取第三个更多的内存。

因此,如果您使用 XPath 提取所有 childNode 元素,您可以 发现它比解析为 DOM 效率低。 XPath 通常是一个 提取 XML 文档的一部分的简单方法。我不推荐 使用它来处理所有的 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 处理,您不必太担心内存占用。

【讨论】:

  • 您引用的有关 XPath 性能的帖子专门针对 DOM4J 产品,不能外推到其他实现。
  • @MichaelKay .. 感谢您帮助我纠正我的错误.. 我忽略了一个事实,即它是针对特定实现的,mea kulpa!谢谢。
【解决方案2】:

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

除此之外,这在很大程度上取决于查询正在做什么(您没有告诉我们)。

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

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

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

【讨论】:

  • xml 会是这样 123ERRR 4487665 12\23\2016 会有几行这样的。我需要做的是整理那里更新的 dt 对同一个手机号码是最新的行
  • 你能再写一遍吗,这次用英文?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-26
  • 2014-08-20
  • 2013-01-26
  • 2023-03-25
  • 1970-01-01
  • 2012-08-17
  • 1970-01-01
相关资源
最近更新 更多