ElementTree Iterparse策略

发布于 2021-01-29 17:54:57

我必须处理足够大(最大1GB)的xml文档,并使用python解析它们。我正在使用iterparse()函数(SAX样式解析)。

我关注的是以下内容,假设您有一个像这样的xml

<?xml version="1.0" encoding="UTF-8" ?>
<families>
  <family>
    <name>Simpson</name>
    <members>
        <name>Homer</name>
        <name>Marge</name>
        <name>Bart</name>
    </members>
  </family>
  <family>
    <name>Griffin</name>
    <members>
        <name>Peter</name>
        <name>Brian</name>
        <name>Meg</name>
    </members>
  </family>
</families>

问题是,当然知道我何时获得姓氏(如辛普森一家)以及何时获得该家庭成员之一的姓名(例如荷马)

到目前为止,我一直在使用“开关”,它会告诉我是否在“成员”标签中,代码看起来像这样

import xml.etree.cElementTree as ET

__author__ = 'moriano'

file_path = "test.xml"
context = ET.iterparse(file_path, events=("start", "end"))

# turn it into an iterator
context = iter(context)
on_members_tag = False
for event, elem in context:
    tag = elem.tag
    value = elem.text
    if value :
        value = value.encode('utf-8').strip()

    if event == 'start' :
        if tag == "members" :
            on_members_tag = True

        elif tag == 'name' :
            if on_members_tag :
                print "The member of the family is %s" % value
            else :
                print "The family is %s " % value

    if event == 'end' and tag =='members' :
        on_members_tag = False
    elem.clear()

这很好,因为输出是

The family is Simpson 
The member of the family is Homer
The member of the family is Marge
The member of the family is Bart
The family is Griffin 
The member of the family is Peter
The member of the family is Brian
The member of the family is Meg

我担心的是,在这个(简单的)示例中,我不得不创建一个额外的变量来知道我在哪个标签(on_members_tag)中想象我要处理的真正的xml示例,它们具有更多的嵌套标签。

还要注意,这是一个简化的示例,因此可以假设我可能面对的是带有更多标签,更多内部标签的xml,并尝试获取不同的标签名称,属性等。

问题是。我在这里做些愚蠢的事吗?我觉得必须对此有一个更优雅的解决方案。

关注者
0
被浏览
39
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    这是一种可能的方法:我们维护路径列表并向后窥视以找到父节点。

    path = []
    for event, elem in ET.iterparse(file_path, events=("start", "end")):
        if event == 'start':
            path.append(elem.tag)
        elif event == 'end':
            # process the tag
            if elem.tag == 'name':
                if 'members' in path:
                    print 'member'
                else:
                    print 'nonmember'
            path.pop()
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看