【发布时间】:2015-02-10 16:51:29
【问题描述】:
我正在尝试使用 Python 2.7 解析 XML 文件。 XML 文件的大小为 370+ MB,包含 6,541,000 行。
XML 文件由以下 300K 块组成:
<Tag:Member>
<fileID id = '123456789'>
<miscTag> 123 </miscTag>
<miscTag2> 456 </miscTag2>
<DateTag> 2008-02-02 </DateTag>
<Tag2:descriptiveTerm>Keyword_1</Tag2:descriptiveTerm>
<miscTag3>6.330016</miscTag3>
<historyTag>
<DateTag>2001-04-16</DateTag>
<reasonTag>Refresh</reasonTag>
</historyTag>
<Tag3:make>Keyword_2</Tag3:make>
<miscTag4>
<miscTag5>
<Tag4:coordinates>6.090,6.000 5.490,4.300 6.090,6.000 </Tag4:coordinates>
</miscTag5>
</miscTag4>
</Tag:Member>
我使用了以下代码:
from xml.dom.minidom import parseString
def XMLParser(filePath):
""" ===== Load XML File into Memory ===== """
datafile = open(filePath)
data = datafile.read()
datafile.close()
dom = parseString(data)
length = len(dom.getElementsByTagName("Tag:Member"))
counter = 0
while counter < length:
""" ===== Extract Descriptive Term ===== """
contentString = dom.getElementsByTagName("Tag2:descriptiveTerm")[counter].toxml()
laterpart = contentString.split("Tag2:descriptiveTerm>", 1)[1]
descriptiveTerm = laterpart.split("</Tag2:descriptiveTerm>", 1)[0]
if descriptiveGroup == "Keyword_1":
""" ===== Extract Make ===== """
contentString = dom.getElementsByTagName("Tag3:make")[counter].toxml()
laterpart = contentString.split("<Tag3:make>", 1)[1]
make = laterpart.split("</Tag3:make>", 1)[0]
if descriptiveTerm == "Keyword_1" and make == "Keyword_2":
""" ===== Extract ID ===== """
contentString = dom.getElementsByTagName("Tag:Member")[counter].toxml()
laterpart = contentString.split("id=\"", 1)[1]
laterpart = laterpart.split("Tag", 1)[1]
IDString = laterpart.split("\">", 1)[0]
""" ===== Extract Coordinates ===== """
contentString = dom.getElementsByTagName("Tag:Member")[counter].toxml()
laterpart = contentString.split("coordinates>", 1)[1]
coordString = laterpart.split(" </Tag4:coordinates>", 1)[0]
counter += 1
所以,我运行了这个,发现它需要大约 27GB 的内存,并且解析上述每个块需要超过 20 秒。所以解析这个文件需要2个月!
我想我写了一些效率低下的代码。谁能帮我改进一下?
非常感谢。
【问题讨论】:
-
从 DOM 转换回 XML 确实是不必要且低效的,并且使用字符串拆分来导航 XML 是非常可怕的。坦率地说,人们通常根本不再使用 minidom,除非他们试图运行为更旧版本的 Python 编写的代码,所以建议的要点是“不要那样做”。 :)
-
我强烈(强烈!)建议使用基于 libxml2 的现代库; lxml 符合要求,尽管 cElementTree 也是可行的。并且永远不要在语法元素上使用字符串拆分来解析您的 XML。
-
实际上,对于这种大小的文件,流式解析器可能是提高效率的更好选择。
-
顺便说一句,
Tag1和Tag2不是标签,而是命名空间,它们需要在父文档中的某处声明xmlns才能成为有效语法,而您在示例中没有给出。
标签: python xml performance minidom