【发布时间】:2020-03-28 13:37:24
【问题描述】:
我有一个像这样的巨大 xml 文件
<environment>
<category name='category1'>
<peoples>
<people>
<name>Mary</name>
<city>NY</city>
<age>10</age>
</people>
<people>
<name>Jane</name>
<city>NY</city>
<age>19</age>
</people>
<people>
<name>John</name>
<city>NY</city>
<age>20</age>
</people>
<people>
<name>Carl</name>
<city>DC</city>
<age>11</age>
</people>
...
</people>
</category>
<category name='category2'>
...
</category
</environment>
我想将 xml 文件和输出解析为字典,其中键是类别的名称(示例中为 category1、category2)和每个类别可能不同的值字典。现在我只对类别 1 感兴趣,我想在其中创建一个字典,其中键是名称,值是年龄,它只包含住在 city = NY 的人
所以最终输出会是这样的:
{ 'cateogory1': { 'Mary': 10, 'Jane': 19, 'John': 20 }, 'cateogory2': {} }
我首先尝试使用 iterparse,但出现内存错误:
result = {}
for _, element in etree.iterparse( 'file.xml', tag = 'category' ):
result[element.get('name')] = {}
if element.get('name') == 'category':
persons = {}
for person in element.findall('peoples/people'):
name, city, age = person.getchildren()
if city.text == 'NY':
persons[ name.text ] = age.text
result[element.get('name')] = persons
element.clear()
return results
所以我的第二次尝试是使用 SAX,但我不熟悉它。我首先从这里获取了一个脚本,但找不到将名字与一个人的城市和年龄相关联的方法:
class CategoryParser(object):
def __init__( self, d ):
self.d = d
def start( self, start, attrib ):
if tag == 'category':
self.group = self.d[attrib['name']] = {}
elif tag == 'people':
#don't know how to access name, city and age for this person
def close( self ):
pass
result = {}
parser = lxml.etree.XMLParser( target=CategoryParser(result) )
lxml.etree.parse( 'file.xml', parser )
实现预期结果的最佳方式是什么?我愿意使用其他方法。
【问题讨论】:
-
你能发布你得到的整个内存错误吗?你应该可以用 iterparse 做到这一点;是读取 XML 的内存错误还是因为您的
result字典太大?
标签: python xml-parsing lxml saxparser