python解析xml生成代码_python:有没有实现为生成器的XML解析器?

xml.etree.cElementTree接近一个正确用法的生成器;默认情况下,每个元素都在其“end”事件之后接收,此时您可以处理它。你应该用元素。清除(),如果处理后不需要它,则可以保存内存。在

这是一个完整的例子,我在这里解析Rhythbox(音乐播放器)库。我使用(c)ElementTree的iterparse,对于我调用的每个已处理元素元素。清除()这样我就节省了不少内存。(顺便说一句,下面的代码是一些sax代码的后续代码,可以完成相同的任务;cElementTree解决方案让人松了一口气,因为1)代码简洁,表达了我需要的内容,而且没有什么比2)它的速度快3倍,3)它使用的内存更少。)import os

import xml.etree.cElementTree as ElementTree

NEEDED_KEYS= set(("title", "artist", "album", "track-number", "location", ))

def _lookup_string(string, strmap):

"""Look up @string in the string map,

and return the copy in the map.

If not found, update the map with the string.

"""

string = string or ""

try:

return strmap[string]

except KeyError:

strmap[string] = string

return string

def get_rhythmbox_songs(dbfile, typ="song", keys=NEEDED_KEYS):

"""Return a list of info dictionaries for all songs

in a Rhythmbox library database file, with dictionary

keys as given in @keys.

"""

rhythmbox_dbfile = os.path.expanduser(dbfile)

lSongs = []

strmap = {}

# Parse with iterparse; we get the elements when

# they are finished, and can remove them directly after use.

for event, entry in ElementTree.iterparse(rhythmbox_dbfile):

if not (entry.tag == ("entry") and entry.get("type") == typ):

continue

info = {}

for child in entry.getchildren():

if child.tag in keys:

tag = _lookup_string(child.tag, strmap)

text = _lookup_string(child.text, strmap)

info[tag] = text

lSongs.append(info)

entry.clear()

return lSongs

现在,我不明白你的期望,你有以下期望吗?在

^{pr2}$

每次调用iterparse时,都会得到一个新的迭代器对象,重新读取文件!如果你想要一个具有迭代器语义的持久对象,你必须在两个循环中引用同一个对象(未经测试的代码):#setup

parseiter = iter(ElementTree.iterparse(rhythmbox_dbfile))

# take one

for event, entry in parseiter:

# parse some entries, then exit loop

# take two

for event, entry in parseiter:

# parse the rest of entries

我认为这可能会令人困惑,因为不同的对象有不同的语义。文件对象总是有一个内部状态并在文件中前进,不管你如何迭代它。一个ElementTree iterparse对象显然不是。关键是认为当你使用for循环时,for总是在你迭代的对象上调用iter()。这是一个比较实验元素树.iterparse对于文件对象:>>> import xml.etree.cElementTree as ElementTree

>>> pth = "/home/ulrik/.local/share/rhythmbox/rhythmdb.xml"

>>> iterparse = ElementTree.iterparse(pth)

>>> iterparse

>>> iter(iterparse)

>>> iter(iterparse)

>>> f = open(pth, "r")

>>> f

>>> iter(f)

>>> iter(f)

您看到的是,对iterparse对象的每次调用都会返回一个新的生成器。但是,file对象有一个必须保存的内部操作系统状态和它自己的迭代器。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值