Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python xml ElementTree可以解析非常大的xml文件吗?_Python_Xml - Fatal编程技术网

Python xml ElementTree可以解析非常大的xml文件吗?

Python xml ElementTree可以解析非常大的xml文件吗?,python,xml,Python,Xml,我正在尝试解析一个大文件(>2GB)的结构化标记数据,但内存不足。这是针对这种情况的XML解析类的最佳方式。请提供更多详细信息。大多数DOM库(如ElementTree)在核心中构建整个文档模型。传统上,当您的模型太大而无法立即放入内存时,您需要使用更面向流的解析器,如 这通常比您预期的要困难,尤其是在用于高阶操作时,如一次处理整个DOM 您的xml文档可能非常简单吗 <entries> <entry>...</entry> <entry>

我正在尝试解析一个大文件(>2GB)的结构化标记数据,但内存不足。这是针对这种情况的XML解析类的最佳方式。请提供更多详细信息。

大多数DOM库(如ElementTree)在核心中构建整个文档模型。传统上,当您的模型太大而无法立即放入内存时,您需要使用更面向流的解析器,如

这通常比您预期的要困难,尤其是在用于高阶操作时,如一次处理整个DOM

您的xml文档可能非常简单吗

<entries>
  <entry>...</entry>
  <entry>...</entry>
</entries>

...
...

这将允许您以更为元素树友好的方式处理数据子集?

我见过的唯一能够处理此类事情的API是pulldom:

Pulldom使用SAXAPI构建部分DOM节点;通过将特定的子树作为一个组拉入,然后在完成后丢弃它们,可以在使用DOM的同时获得SAX的内存效率

这是一个不完整的API;当我使用它的时候,我必须修改它以使它完全可用,但它是一个基础。我不再使用它了,所以我不记得我要添加什么;只是一个预先警告

非常慢

XML是处理大型数据集的一种非常糟糕的格式。如果您可以控制源数据,并且对数据集有意义,那么最好将数据分割成更小的块,完全解析到内存中


另一种选择是使用SAXAPI,但是直接使用SAXAPI做任何不寻常的事情都是非常痛苦的。

查看
iterparse()
函数。可以找到如何使用它来解析非常大的文档的描述。

正如其他回答者所说的
ElementTree
是一个DOM解析器,尽管它有方法

为了减少内存占用,我使用了一个真正的SAX解析器。是我用于解决方案的链接。官方文件。以下是我的XML:

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
    <entity storageTableName="table7113" tableName="TableBusinessName">
        <attribute storageFieldName="field7114" fieldName="BusinessName1" />
        <attribute storageFieldName="field7115" fieldName="BusinessName2" />
        . . .
    </entity>
    . . .
</metadata>
工作足够快

以防万一,请提供更多细节:

import my_package as p


if __name__ == "__main__":

    with open('<my_path>/<my_file>.xml', 'r', encoding='utf_8') as file:
        entity_names, attr_names = p.get_model_names(file)
将我的_包作为p导入
如果名称=“\uuuuu main\uuuuuuuu”:
以open('/.xml',r',encoding='utf_8')作为文件:
实体名称,属性名称=p.get\u模型名称(文件)

是的,十年后,已经有许多处理大型文件的新解决方案。下面我为大家推荐一个

例如,文件test.xml的内容如下

<?xml version="1.0" encoding="UTF-8"?>
<breakfast_menu>
    <food>
        <name>Strawberry Belgian Waffles</name>
        <price>$7.95</price>
        <description>
        Light Belgian waffles covered with strawberries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    <food>
        <name>Berry-Berry Belgian Waffles</name>
        <price>$8.95</price>
        <description>
        Belgian waffles covered with assorted fresh berries and whipped cream
        </description>
        <calories>900</calories>
    </food>
    ......
</breakfast_menu>
结果:

['Strawberry Belgian Waffles', '$7.95', 'Light Belgian waffles covered with strawberries and whipped cream', '900']
...

iterparse()函数将解决您的问题,我最近在iterparse的帮助下轻松解析了一个1GB的xml文档:)我刚刚找到了pulldom库,它看起来非常棒——如果它以正常速度运行的话。太慢了。我用一个完整的domxmlementtree解析了一个xml文件,并花了60秒(1分钟)将其放入一个数据帧中。pulldom库仅读取文件(无解析)就花费了600秒(10分钟)。为什么这东西这么慢?
from simplified_scrapy import SimplifiedDoc, utils

doc = SimplifiedDoc()
doc.loadFile('test.xml', lineByline=True)

for food in doc.getIterable('food'):
    print (food.children.text)
['Strawberry Belgian Waffles', '$7.95', 'Light Belgian waffles covered with strawberries and whipped cream', '900']
...