如何在Java中有效地解析200,000个XML文件?

时间:2011-04-04 23:47:19

标签: java xml xml-parsing

我有200,000个XML文件,我想解析并存储在数据库中。

以下是一个示例:https://gist.github.com/902292

这与XML文件一样复杂。这也将在小型VPS(Linode)上运行,因此内存很紧张。

我想知道的是:

1)我应该使用DOM还是SAX解析器? DOM似乎更容易,更快,因为每个XML都很小。

2)关于所述解析器的简单教程在哪里? (DOM或SAX)

由于

修改

我尝试了DOM路由,即使每个人都建议使用SAX。主要是因为我找到了一个“更容易”的DOM教程,我认为由于平均文件大小约为3k - 4k,因此很容易将其保存在内存中。

但是,我编写了一个递归例程来处理所有200k文件,它通过它们大约有40%,然后Java内存不足。

这是该项目的一部分。 https://gist.github.com/905550#file_xm_lparser.java

我现在应该抛弃DOM而只使用SAX吗?看起来像这样的小文件DOM应该能够处理它。

此外,速度“足够快”。解析2000个XML文件需要大约19秒(在Mongo插入之前)。

由于

6 个答案:

答案 0 :(得分:4)

为什么不使用正确的XML数据库(如Berkeley DB XML)?然后你可以直接转储文档,并根据需要创建索引(例如在HotelID上)。

答案 1 :(得分:3)

分而治之 将200,000个文件拆分为多个存储桶并并行化解析/插入。如果您想保持简单,请查看Java 5 Executors;如果这是一项重复性任务,请使用spring-batch,在这种情况下,您可以从高级框架中受益。

<强> API

使用SAX可以提供帮助,但不是必需的,因为您不打算保留解析后的模型(即您所做的只是解析,插入然后释放解析后的数据,此时对象符合GC的条件) 。查看一个简单的API,例如JDOM

其他想法

您可以实现生产者/消费者类型的模型,其中生产者生成解析后创建的pojo,并且使用者获取pojo并将其插入到db中。这样做的好处是你可以 batch the insert 来获得更高的性能。

答案 2 :(得分:2)

使用SAX,或者如果你愿意,可以使用StAX。忘了DOM。使用像aalto这样的有效库。

我确信与发出数据库请求相比,解析会非常便宜。

但如果你只需要做一次,那么200k就不是那么大了。

答案 3 :(得分:2)

SAX总是快速击败DOM。但是,既然你说XML文件很小,你可以继续使用DOM解析器。您可以做的一件事就是加速创建一个Thread-Pool并在其中执行数据库操作。多线程更新将显着提高性能。

  • Lalith

答案 4 :(得分:0)

SAX将比DOM更快,如果您要解析200,000个文件,这可能是一个问题。

答案 5 :(得分:0)

StAX比SAX快,这比DOM快得多。如果性能超级关键,您还可以考虑构建一个特殊的编译器来解析XML文件。但通常lexing和解析并不是StAX的问题,而是“后处理”。