我有一个包含 XML 文件的完整目录(~10 3、 10 4),我需要从中提取几个字段的内容。我测试了不同的 xml 解析器,因为我不需要验证内容(昂贵),所以我想简单地使用 xml.parsers.expat (最快的)来遍历文件,一个一个地提取数据。
- 有没有更有效的方法?(简单的文本匹配不起作用)
- 我是否需要为每个新文件(或字符串)发出一个新的 ParserCreate() 或者我可以为每个文件重复使用相同的 ParserCreate() 吗?
- 有什么注意事项吗?
谢谢!
我有一个包含 XML 文件的完整目录(~10 3、 10 4),我需要从中提取几个字段的内容。我测试了不同的 xml 解析器,因为我不需要验证内容(昂贵),所以我想简单地使用 xml.parsers.expat (最快的)来遍历文件,一个一个地提取数据。
谢谢!
通常,我会建议使用 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"
,但您也可以初始化解析器,以便在解析新元素时告诉您它们的信息。您无法保证此时所有子元素都已被解析,但如果您只对此感兴趣,属性就在那里。
另一点是您可以提前停止从迭代器中读取元素,即在整个文档被处理之前。
如果文件很大(是吗?),有一个常见的习惯用法来保持内存使用量不变,就像在流解析器中一样。
最快的方法是匹配字符串(例如,正则表达式)而不是解析 XML——这取决于您的 XML,这实际上可以工作。
但最重要的是:不要考虑几个选项,只需实施它们并在一个小集合上计时。这将花费大致相同的时间,并且会为您提供真实的数字,确实会推动您前进。
编辑:
如果您知道 XML 文件是使用相同的算法生成的,那么根本不进行任何 XML 解析可能更有效。例如,如果您知道数据在第 3、4 和 5 行,您可以逐行阅读文件,然后使用正则表达式。
当然,如果文件不是机器生成的,或者来自不同的生成器,或者生成器随时间发生变化,那么这种方法就会失败。但是,我很乐观,它会更有效率。
是否回收解析器对象在很大程度上无关紧要。将创建更多对象,因此单个解析器对象并不算多。
您没有指出的一件事是您是否正在将 XML 读入某种 DOM。我猜你可能不是,但如果你是,不要。请改用 xml.sax。使用 SAX 而不是 DOM 将显着提升性能。