大型XML文件的随机访问

4
我有一组工具,可以对大型XML文件(MediaWiki dump files)进行索引,并使用这些索引随机访问存储在文件中的单个记录。它运行得非常好,但我是通过字符串函数和/或正则表达式来“解析”XML,而不是使用真正的XML解析器,如果将来文件创建方式发生变化,这种解决方案就会变得脆弱。
一些或大多数XML解析器是否有处理此类事情的方法?
(我有用C、Perl和Python编写的工具版本。将整个文件解析成某种数据库或将其映射到内存中不是选项。)
更新:
以下是粗略的统计数据以供比较:我使用的文件大多每周发布一次左右,当前文件的大小为1,918,212,991字节。我的索引工具的C版本在我的上网本上需要几分钟时间,并且只需针对每个新的XML文件运行一次。更少的情况下,我使用同样的工具在另一个XML文件上,该文件的当前大小为30,565,654,976字节,并在2010年仅更新了8次。
5个回答

1

我认为你应该将这些数据存储在一个 XML 数据库中,比如 exist-DB,而不是创建自己的工具来完成 XML 数据库所提供的一小部分功能。


你能给出一些理由吗?我不需要做更多的事情,只需要完成非常小的子集。我将会研究一下exist-DB,但是它在速度方面如何比较呢?显然,这至少意味着需要增加一倍所需的存储空间。 - hippietrail

1

VTD-XML 看起来是第一个认真尝试解决这个问题的工具:

全球最节省内存(仅为 XML 文档大小的 1.3 倍至 1.5 倍)的随机访问 XML 解析器

(VTD-XML 在 StackOverflow 上甚至有自己的标签,因此您可以关注与它相关的问题等:


1
我想知道为什么一年里没有人评论这个答案。这种用例是如此罕见吗?@hippietrail,这对你有用吗? - fho
@Florian: 我其实从未尝试过。当时我玩耍的编程语言中没有实现/库/粘合剂,而维基百科XML转储文件的格式仍然与我的旧简单方法不兼容。但我同意你的观点,似乎在SO这里没有人提到这样的用例... - hippietrail
也许只是选择合适的工具来做正确的工作的问题。XML在随机访问和大文件同时进行时并不是很好。另一方面,如果我只有一个大量的XML转储,如果被要求在这些文件中提供随机访问,我没有太多选择。考虑购买更多的RAM并使用DOM,但最终我们在几台计算机上创建了非常大的文件,并且购买更多的内存只会延迟问题的解决。 - fho

1

如果你正在使用Python,建议尝试lxml - 它非常快速和灵活,其速度比正则表达式相当快。在任何语言中都比其他替代方案要快得多,而且没有妥协。

使用iterparse来分步浏览维基百科文章。

请注意,这并不会让您在dump中随机访问文章(这是一个完全合理的请求!) - 但iterparse将提供一个快速且易于使用的“仅向前”指针...而lxml可能是解析通过其他方式fseek'd到块的正确工具。

这是我找到的最好的文档:

http://infohost.nmt.edu/tcc/help/pubs/pylxml/web/index.html

(请尝试PDF版本)

它现在是标准Python发行版的一部分。


嗯,如果正则表达式出现问题,这可能对创建索引很有用,但正如你所指出的那样,对于实际的随机访问并不适用。 - hippietrail

0

XML是一种结构化格式。因此,随机访问并没有太多意义-您必须知道您要去哪里。

正则表达式还需要将整个字符串加载到内存中。这仍然比DOM更好,因为DOM通常比XML文件的大小大3-4倍。

这些情况的典型解决方案是SAX,其中这些解决方案具有非常小的内存占用,但它们就像一个单向游标:因此,您不能进行随机访问,您必须遍历树以到达您所需的位置。如果您正在使用.NET,则可以使用XmlTextReader

如果XML不经常更新,则索引也很有用,因为创建此类索引可能很昂贵。


1
如果这真的没有太多意义,那么为什么W3要花费如此多的精力来定义XML二进制表示的随机访问呢?请参见(http://www.w3.org/TR/xbc-properties/#random-access等)。 - Abel

-1
XPath比字符串/正则表达式“解析”要好得多,但是XPath需要将XML文档首先解析到内存DOM中,如果您的文档非常大,可能会遇到内存问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接