3

我有一个包含 XML 文件的完整目录(~10 3、 10 4),我需要从中提取几个字段的内容。我测试了不同的 xml 解析器,因为我不需要验证内容(昂贵),所以我想简单地使用 xml.parsers.expat (最快的)来遍历文件,一个一个地提取数据。

  1. 有没有更有效的方法?(简单的文本匹配不起作用)
  2. 我是否需要为每个新文件(或字符串)发出一个新的 ParserCreate() 或者我可以为每个文件重复使用相同的 ParserCreate() 吗?
  3. 有什么注意事项吗?

谢谢!

4

4 回答 4

4

通常,我会建议使用 ElementTree 的iterparse,或者为了额外的速度,使用lxml中的对应物。还可以尝试使用Processing(2.6 内置)来并行化。

重要的iterparse是您在解析元素(子)结构时得到它们。

import xml.etree.cElementTree as ET
xml_it = ET.iterparse("some.xml")
event, elem = xml_it.next()

event在这种情况下将始终是字符串"end",但您也可以初始化解析器,以便在解析新元素时告诉您它们的信息。您无法保证此时所有子元素都已被解析,但如果您只对此感兴趣,属性就在那里。

另一点是您可以提前停止从迭代器中读取元素,即在整个文档被处理之前。

如果文件很大(是吗?),有一个常见的习惯用法来保持内存使用量不变,就像在流解析器中一样。

于 2008-12-08T13:01:56.507 回答
3

最快的方法是匹配字符串(例如,正则表达式)而不是解析 XML——这取决于您的 XML,这实际上可以工作。

但最重要的是:不要考虑几个选项,只需实施它们并在一个小集合上计时。这将花费大致相同的时间,并且会为您提供真实的数字,确实会推动您前进。

编辑:

  • 这些文件是在本地驱动器还是网络驱动器上?网络 I/O 会在这里杀死你。
  • 问题并行化很简单——您可以在多台计算机(或多核计算机上的多个进程)之间拆分工作。
于 2008-12-05T18:08:02.210 回答
1

如果您知道 XML 文件是使用相同的算法生成的,那么根本不进行任何 XML 解析可能更有效。例如,如果您知道数据在第 3、4 和 5 行,您可以逐行阅读文件,然后使用正则表达式。

当然,如果文件不是机器生成的,或者来自不同的生成器,或者生成器随时间发生变化,那么这种方法就会失败。但是,我很乐观,它更有效率。

是否回收解析器对象在很大程度上无关紧要。将创建更多对象,因此单个解析器对象并不算多。

于 2008-12-05T17:49:00.673 回答
1

您没有指出的一件事是您是否正在将 XML 读入某种 DOM。我猜你可能不是,但如果你是,不要。请改用 xml.sax。使用 SAX 而不是 DOM 将显着提升性能。

于 2008-12-06T00:52:34.390 回答