使用 python 在 xml 文件中使用循环修改元素文本
Modify element text with loop in xml file using python
我一直在使用 python 和 lxml 库以及 ElementTree 对 .xml 文件进行一些修改。我有这个结果:
<component xmlns:xsi="http://www.w3.orgr">
<memoryMaps>
<memoryMap>
<name>name</name>
<description>description</description>
<peripheral>
<name>periph</name>
<description>description</description>
<baseAddress>0x0</baseAddress>
<range>0x8</range>
<width>32</width>
<registers>
<register>
<name>reg1</name>
<displayName>1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>1</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>1</displayName>
..................
</register>
</registers>
</peripheral>
</memoryMap>
</memoryMaps>
</component>
我现在想要的是在每个 'register' 中都有 'name' 和 'displayName' 具有相同的文本(通过复制 displayName 中的名称文本),如下所示:
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
我在解析我的文件后尝试了这样的代码:
for register in root.findall('.//register'):
tempo = register.find('.//name').text
for EL in root.iter('displayName'):
EL.text = tempo
这似乎只在最后一个寄存器中替换正确,其余寄存器的显示名称错误。我知道我的循环可能有问题?
请指教
谢谢!
from lxml import etree
root = etree.parse(r'<your file.xml>')
for name in root.xpath('//name[./following-sibling::displayName]'):
name.getnext().text = name.text
print( etree.tostring(root, pretty_print=True).decode('utf-8') )
打印:
<component xmlns:xsi="http://www.w3.orgr">
<memoryMaps>
<memoryMap>
<name>name</name>
<description>description</description>
<peripheral>
<name>periph</name>
<description>description</description>
<baseAddress>0x0</baseAddress>
<range>0x8</range>
<width>32</width>
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
</peripheral>
</memoryMap>
</memoryMaps>
</component>
给你推荐一个简单的库。
from simplified_scrapy import SimplifiedDoc, utils
# xml = utils.getFileContent('your xml path')
xml = '''
<registers>
<register>
<name>reg1</name>
<displayName>1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>1</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>1</displayName>
..................
</register>
</registers>
'''
doc = SimplifiedDoc(xml) # create doc
registers = doc.selects('register')
for r in registers:
r.displayName.setContent(r.name.html)
# Or
names = doc.selects('register>name')
for n in names:
n.setContent(n.next.html)
# Or
# n.setContent(n.getNext('displayName').html)
print(doc.html)
结果:
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
Here 是更多的例子。这个库很容易使用。
我一直在使用 python 和 lxml 库以及 ElementTree 对 .xml 文件进行一些修改。我有这个结果:
<component xmlns:xsi="http://www.w3.orgr">
<memoryMaps>
<memoryMap>
<name>name</name>
<description>description</description>
<peripheral>
<name>periph</name>
<description>description</description>
<baseAddress>0x0</baseAddress>
<range>0x8</range>
<width>32</width>
<registers>
<register>
<name>reg1</name>
<displayName>1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>1</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>1</displayName>
..................
</register>
</registers>
</peripheral>
</memoryMap>
</memoryMaps>
</component>
我现在想要的是在每个 'register' 中都有 'name' 和 'displayName' 具有相同的文本(通过复制 displayName 中的名称文本),如下所示:
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
我在解析我的文件后尝试了这样的代码:
for register in root.findall('.//register'):
tempo = register.find('.//name').text
for EL in root.iter('displayName'):
EL.text = tempo
这似乎只在最后一个寄存器中替换正确,其余寄存器的显示名称错误。我知道我的循环可能有问题?
请指教 谢谢!
from lxml import etree
root = etree.parse(r'<your file.xml>')
for name in root.xpath('//name[./following-sibling::displayName]'):
name.getnext().text = name.text
print( etree.tostring(root, pretty_print=True).decode('utf-8') )
打印:
<component xmlns:xsi="http://www.w3.orgr">
<memoryMaps>
<memoryMap>
<name>name</name>
<description>description</description>
<peripheral>
<name>periph</name>
<description>description</description>
<baseAddress>0x0</baseAddress>
<range>0x8</range>
<width>32</width>
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
</peripheral>
</memoryMap>
</memoryMaps>
</component>
给你推荐一个简单的库。
from simplified_scrapy import SimplifiedDoc, utils
# xml = utils.getFileContent('your xml path')
xml = '''
<registers>
<register>
<name>reg1</name>
<displayName>1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>1</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>1</displayName>
..................
</register>
</registers>
'''
doc = SimplifiedDoc(xml) # create doc
registers = doc.selects('register')
for r in registers:
r.displayName.setContent(r.name.html)
# Or
names = doc.selects('register>name')
for n in names:
n.setContent(n.next.html)
# Or
# n.setContent(n.getNext('displayName').html)
print(doc.html)
结果:
<registers>
<register>
<name>reg1</name>
<displayName>reg1</displayName>
....
</register>
<register>
<name>reg2</name>
<displayName>reg2</displayName>
.................
</register>
<register>
<name>reg3</name>
<displayName>reg3</displayName>
..................
</register>
</registers>
Here 是更多的例子。这个库很容易使用。