python - findall 或 finditer 可以在这个 python ElementTree 示例中使用吗?

标签 python xml elementtree

我想在 python 中使用 ElementTree 处理以下 xml。 当 UserValue 标题为 THIRD 并且其值不为空时,我需要查找所有实例名称。因此,在此示例中,结果将是弹珠和鼠标。

<?xml version="1.0" encoding="utf-8"?>
<Data>
    <Instance id="61" name="atom">
        <UserData id="30">
            <UserValue value="" title="FIRST"></UserValue>
            <UserValue value="" title="SECOND"></UserValue>
            <UserValue value="" title="THIRD"></UserValue>
            <UserValue value="watch" title="FOURTH"></UserValue>
        </UserData>
    </Instance>
    <Instance id="64" name="marble" ref="33">
        <UserData id="34">
            <UserValue value="" title="FIRST"></UserValue>
            <UserValue value="stuff" title="SECOND"></UserValue>
            <UserValue value="airplane" title="THIRD"></UserValue>
            <UserValue value="" title="FOURTH"></UserValue>
        </UserData>
    </Instance>
    <Instance id="65" name="rock">
        <UserData id="36">
            <UserValue value="" title="FIRST"></UserValue>
            <UserValue value="" title="SECOND"></UserValue>
            <UserValue value="" title="THIRD"></UserValue>
            <UserValue value="" title="FOURTH"></UserValue>
        </UserData>     
    </Instance>
    <Instance id="66" name="mouse">
        <UserData id="38">
            <UserValue value="" title="FIRST"></UserValue>
            <UserValue value="" title="SECOND"></UserValue>
            <UserValue value="rocket" title="THIRD"></UserValue>
            <UserValue value="" title="FOURTH"></UserValue>
        </UserData>     
    </Instance>
</Data>

这是我想出的Python代码。它工作正常并返回大理石和鼠标。 有没有办法使用 findall 或 finditer 来做同样的事情?

另一个问题是 ElementTree 似乎将整个 xml 加载到内存中进行处理,这对于我接近 300MB 的真实 xml 来说可能是一个问题。

import xml.etree.ElementTree as xml

tree = xml.parse("example.xml")

for node in tree.iter('Instance'):

    name = node.get('name')

    for col in node.iter('UserValue'):
        title = col.attrib.get('title')
        value = col.attrib.get('value')

        if (title == "THIRD" and value != ""):
            print "     name =", name

最佳答案

我建议您使用lxml 。您可以将 xpath 表达式与 lxml 一起使用。

import lxml.etree

root = lxml.etree.parse("example.xml")
for instance in root.xpath('//Instance[descendant::UserValue[@title = "THIRD"][@value != ""]]'):
    print instance.get('name')

如果上面的代码占用太多内存,请尝试以下代码:

import lxml.etree

class InstanceNamePrinter(object):
    def start(self, tag, attrib):
        if tag == 'Instance':
            self.name = attrib['name']
        elif tag == 'UserValue':
            if attrib['title'] == 'THIRD' and attrib['value'] != '':
                print self.name
    def close(self):
        pass

with open('example.xml') as xml:
    parser = lxml.etree.XMLParser(target=InstanceNamePrinter())
    lxml.etree.parse(xml, parser)

关于python - findall 或 finditer 可以在这个 python ElementTree 示例中使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17619123/

相关文章:

python - 错误: incompatible types when assigning to type ‘__complex__ double *’ from type ‘complex double’

javascript - CEF Python ExecuteJavascript 不会设置输入元素的值

python - 如何从Python覆盖率单元测试中省略(删除)虚拟环境(venv)?

java - 缺少 Android 操作栏和菜单选项

xml - 使用 XPath 从 Postgres XML 列中提取数据

python - 使用 Python 按属性查找 ElementTree 中的所有元素

python - 使用 python/ElementTree 和命名空间创建 xml 文档

python - 对列中具有公共(public)值的行使用 meshgrid

C# - 当 webRequest 发送 XML 时,将 Base64 安全为 Gif?

python - 如何使用 QName(python xml.etree.ElementTree?)