一次只读取一个元素时,如何覆盖单个属性值?
具体地说,我正在使用xml.etree.cElementTree.iterparse()
来读取每个单独的元素。然后,我要更改属性值。
然后我要做的是用original element
覆盖changed element
。
这是到目前为止的示例代码:
osm_file = open(sample.osm, 'r+')
for event, elem in ET.iterparse(osm_file events=("start",)):
# Making some changes
elem.attrib['v'] = 'new_value'
# Some how write the elem back to the XML file
我不能做的一件事是将整个XML文件读入python,因为该文件太大。
答案 0 :(得分:1)
解释了为什么这不可能。
那可能行不通。 XML处理不知道数据来自文件,因此无法在文件中完全相同的位置“回写”更改后的值。即使可以:在没有重写整个文件的情况下,用较短或较长的文本替换文件中的文本在物理上也是不可能的。 (唯一的例外是“长度完全相同的文本”和“数据在最后”。)– usr2564301
答案 1 :(得分:1)
iterparse仍然处理整个树。您无法避免:
http://effbot.org/zone/element-iterparse.htm#incremental-parsing
增量解析#请注意,iterparse仍会构建一棵树,只是 就像解析一样,但是您可以安全地重新排列或删除树的一部分 同时解析。例如,要解析大型文件,您可以摆脱 元素处理后:
对于事件,iterparse中的elem(源): 如果elem.tag ==“ record”: ...处理记录元素... elem.clear()
如果您的XML文件太大,无法在程序中处理,则需要考虑其他数据存储格式,例如数据库。
否则,您可以使用sed和awk或其他工具对文本文件进行一些文件操作魔术。
答案 2 :(得分:0)
我最近也一直在处理大型文件,但无法将其容纳在内存中。为了解决这个问题,我整理了一个简单的程序包bigread
(pip install bigread
),该程序包可将文件的n行立即流进RAM:
from bigread import Reader
# this will be the output file
with open('updated.xml', 'w') as out:
# read the input file
for i in Reader(file='input.xml', block_size=1):
# check if this is a line you need to operate on
if i.lstrip()[:5] == '<tag ':
# replace the target attribute
i = i.replace(' attr="cats" ', ' attr="dogs" ')
# write the new line to disk
out.write(i + '\n')