用Python编辑XML文件中所有childNodes的文本
我想在一个XML文件中编辑所有名为“Volume”的标签里的文本,方法是把这些文本乘以用户输入的一个数字。“Volume”标签里的文本总是一个数字。我的代码到目前为止能正常工作,但只对第一个“Volume”文本有效。
这是XML的一个例子:
<blah>
<moreblah> sometext </moreblah> ;
<blah2>
<blah3> <blah4> 30 </blah4> <Volume> 15 </Volume> </blah3>
</blah2>
</blah>
<blah>
<moreblah> sometext </moreblah> ;
<blah2>
<blah3> <blah4> 30 </blah4> <Volume> 25 </Volume> </blah3>
</blah2>
</blah>
这是我的Python代码:
#import modules
import xml.dom.minidom
from xml.dom.minidom import parse
import os
import fileinput
#create a backup of original file
new_file_name = 'blah.xml'
old_file_name = new_file_name + "_old"
os.rename(new_file_name, old_file_name)
#find all instances of "Volume"
doc = parse(old_file_name)
volume = doc.getElementsByTagName('Volume')[0]
child = volume.childNodes[0]
txt = child.nodeValue
#ask for percentage input
print
percentage = raw_input("Set Volume Percentage (1 - 100): ")
if percentage.isdigit():
if int(percentage) <101 >1:
print 'Thank You'
#append text of <Volume> tag
child.nodeValue = str(int(float(txt) * (int(percentage)/100.0)))
#persist changes to new file
xml_file = open(new_file_name, "w")
doc.writexml(xml_file)
xml_file.close()
#remove XML Declaration
text = open("blah.xml", "r").read()
text = text.replace('<?xml version="1.0" ?>', '')
open("blah.xml", "w").write(text)
else:
print
print 'Please enter a number between 1 and 100.'
print
print 'Try again.'
print
print 'Exiting.'
xml_file = open(new_file_name, "w")
doc.writexml(xml_file)
xml_file.close()
os.remove(old_file_name)
我知道在我的代码中,有“doc.getElementsByTagName('Volume')[0]”,这表示“Volume”标签的第一个实例,但我这样做只是为了测试看看是否有效。所以我知道代码的运行方式是正确的。不过,我想知道有没有人能给我一些建议,或者告诉我最简单的方法来把用户输入的百分比应用到所有的“Volume”标签实例上。
这也是我第一次尝试Python,所以如果你看到有什么奇怪的地方,请告诉我。
谢谢你的帮助!
1 个回答
2
如果你使用更现代的XML接口,比如ElementTree(这是标准库的一部分)或者lxml(更高级一些),你会开心很多。
在ElementTree或lxml中,你可以使用XPath(或者类似的东西),这让你在查找XML文档中的元素和属性时,语法更加灵活。
在ElementTree中:
volumes = my_parsed_xml_file.find('.//Volume')
...这段代码会找到所有的Volume
元素。
如果你继续使用现在的语法,像这样:
doc.getElementsByTagName('Volume')[0]
...你实际上是在特定地请求第一个(零索引)Volume
。如果你想处理所有的Volume
,你需要用一个循环:
for volume in doc.getElementsByTagName('Volume'):
child = volume.childNodes[0]
// ... rest of your code inside the loop
如果你对循环这样的结构不太熟悉,建议你先回去看看一些编程入门指南,因为没有一些基础知识,事情会变得相当复杂。祝你好运!