如何在Python中更新/修改XML文件?

问题描述 投票:0回答:9

我有一个 XML 文档,我想在它包含数据后对其进行更新。

我考虑过以

"a"
(追加)模式打开 XML 文件。问题是新数据将写入根结束标记之后。

如何删除文件的最后一行,然后从该点开始写入数据,然后关闭根标签?

当然,我可以读取整个文件并进行一些字符串操作,但我认为这不是最好的主意..

python xml io
9个回答
101
投票

使用

ElementTree

import xml.etree.ElementTree

# Open original file
et = xml.etree.ElementTree.parse('file.xml')

# Append new tag: <a x='1' y='abc'>body text</a>
new_tag = xml.etree.ElementTree.SubElement(et.getroot(), 'a')
new_tag.text = 'body text'
new_tag.attrib['x'] = '1' # must be str; cannot be an int
new_tag.attrib['y'] = 'abc'

# Write back to file
#et.write('file.xml')
et.write('file_new.xml')

注意:输出写入

file_new.xml
供您实验,写回
file.xml
将替换旧内容。

重要提示:ElementTree 库将属性存储在字典中,因此,这些属性在 xml 文本中列出的顺序将不会保留。相反,它们将按字母顺序输出。 (另外,评论被删除了。我觉得这很烦人)

即:xml输入文本

<b y='xxx' x='2'>some body</b>
将输出为
<b x='2' y='xxx'>some body</b>
(按字母顺序排列后定义了顺序参数)

这意味着当将原始文件和更改后的文件提交到修订控制系统(例如 SVN、CSV、ClearCase 等)时,两个文件之间的差异可能看起来不太漂亮。


32
投票

有用的 Python XML 解析器:

  1. Minidom - 功能齐全但有限
  2. ElementTree - 不错的性能,更多功能
  3. lxml - 高性能在大多数情况下,高功能,包括真正的xpath支持

其中任何一个都比尝试将 XML 文件更新为文本字符串更好。

这对您意味着什么:

使用您选择的 XML 解析器打开文件,找到您感兴趣的节点,替换值,将文件序列化回来。


12
投票

快速而简单的方法,你绝对不应该这样做(见下文),是使用readlines()

将整个文件读入字符串列表。我写这篇文章是为了防止您正在寻找快速简单的解决方案。

只需使用

open()

 打开文件,然后调用 
readlines()
 方法即可。您将得到的是文件中所有字符串的列表。现在,您可以轻松地在最后一个元素之前添加字符串(只需将最后一个元素之前的一个元素添加到列表中)。最后,您可以使用 
writelines()
 将这些写回文件。

一个例子可能会有所帮助:

my_file = open(filename, "r") lines_of_file = my_file.readlines() lines_of_file.insert(-1, "This line is added one before the last line") my_file.writelines(lines_of_file)

您不应该这样做的原因是,除非您正在做一些非常快速且肮脏的事情,否则您应该使用 XML 解析器。这个库允许您使用 DOM、树和节点等概念智能地使用 XML。这不仅是使用 XML 的正确方法,也是标准方法,使您的代码更加可移植,并且更容易被其他程序员理解。

蒂姆的回答提到为此目的检查

xml.dom.minidom

,我认为这是一个好主意。
    


4
投票
虽然我同意 Tim 和 Oben Sonne 的观点,即您应该使用 XML 库,但仍然有一些方法可以将其作为简单的字符串对象进行操作。

我可能不会尝试使用单个文件指针来描述您所描述的内容,而是将文件读入内存,编辑它,然后写出来。:

inFile = open('file.xml', 'r') data = inFile.readlines() inFile.close() # some manipulation on `data` outFile = open('file.xml', 'w') outFile.writelines(data) outFile.close()
    

3
投票
对于修改,您可以使用

xml

 中的 
tag.text。这是片段:

import xml.etree.ElementTree as ET tree = ET.parse('country_data.xml') root = tree.getroot() for rank in root.iter('rank'): new_rank = int(rank.text) + 1 rank.text = str(new_rank) tree.write('output.xml')
代码中的

rank

是标签的示例,具体取决于您的XML文件内容。


2
投票
您真正想做的是使用 XML 解析器并使用提供的 API 附加新元素。

然后只需覆盖该文件即可。

最容易使用的可能是 DOM 解析器,如下所示:

http://docs.python.org/library/xml.dom.minidom.html


2
投票
为了使这个过程更加健壮,您可以考虑使用 SAX 解析器(这样您就不必将整个文件保存在内存中),读取和写入直到树的末尾,然后开始追加。


0
投票
您应该使用特定的 XML 模块读取 XML 文件。这样您就可以编辑内存中的 XML 文档并将更改后的 XML 文档重写到文件中。

这里是快速入门:

http://docs.python.org/library/xml.dom.minidom.html

还有许多其他 XML 实用程序,哪一个最好取决于 XML 文件的性质以及您想要编辑它的方式。


0
投票
正如 Edan Maor 所解释的那样,快速而肮脏的方法(对于 [utc-16] 编码的 .xml 文件),您应该

为了 Edam Maor 解释的原因而这样做,可以使用以下 python 2.7 代码来完成时间限制不允许您学习(适当的)XML 解析。

假设您想要:

    删除原始 xml 文件中的最后一行。
  1. 添加一行
  2. 替换一行
  3. 关闭根标签。
它在python 2.7中工作,修改位于文件夹“a”中名为“b.xml”的.xml文件,其中“a”位于python的“工作文件夹”中。它将新修改的文件输出为文件夹“a”中的“c.xml”,在 python 2.7 之外进一步使用时不会产生编码错误(对我来说)。

pattern = '<Author>' subst = ' <Author>' + domain + '\\' + user_name + '</Author>' line_index =0 #set line count to 0 before starting file = io.open('a/b.xml', 'r', encoding='utf-16') lines = file.readlines() outFile = open('a/c.xml', 'w') for line in lines[0:len(lines)]: line_index =line_index +1 if line_index == len(lines): #1. & 2. delete last line and adding another line in its place not writing it outFile.writelines("Write extra line here" + '\n') # 4. Close root tag: outFile.writelines("</phonebook>") # as in: #http://tizag.com/xmlTutorial/xmldocument.php else: #3. Substitue a line if it finds the following substring in a line: pattern = '<Author>' subst = ' <Author>' + domain + '\\' + user_name + '</Author>' if pattern in line: line = subst print line outFile.writelines(line)#just writing/copying all the lines from the original xml except for the last.
    
© www.soinside.com 2019 - 2024. All rights reserved.