python - 使用python搜索和替换XMLfile中的元素
问题描述
我需要在 XML 文件中搜索元素并替换为另一个值。替换应该只发生在条件匹配的行上。
我有以下 xml 文件。
<?xml vn="1.0" encoding="UTF-8"?>
<proj>
<mV>4.0.0</mV>
<gId>com.test</gId>
<aId>console</aId>
<vn>1.0</vn>
<bld>
<plugins>
<plugin>
<gId>org.apache.maven.plugins</gId>
<aId>maven-compiler-plugin</aId>
<vn>1.1</vn>
<configuration>
<source>1.0</source>
<target>1.0</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</bld>
<dps>
<dp>
<gId>org.sk</gId>
<aId>sk-api</aId>
<vn>1.7.20</vn>
</dp>
<dp>
<gId>org.sk</gId>
<aId>sk-log</aId>
<vn>1.7.25</vn>
</dp>
</dps>
</proj>
下面是替换代码。
aIdValue = "sk-log"
tree = ET.parse('test.xml')
al_rt = tree.getal_rt()
dp = al_rt.findall(".//xmlns:dp")
for d in dp:
aId = d.find("xmlns:aId")
vn = d.find("xmlns:vn")
if aIdValue == aId.text:
print aId.text
print vn.text
vn.text = vn.text
tree.write('test.xml')
所以在这里我从打印语句中获取值aId.text
issk-log
和vn.text
is 1.7.25
。我只需要在该特定行1.7.25
中用on 替换。somevalue
上面的代码对我不起作用。我怎样才能做到这一点?
预期的输出将是
<?xml vn="1.0" encoding="UTF-8"?>
<proj>
<mV>4.0.0</mV>
<gId>com.test</gId>
<aId>console</aId>
<vn>1.0</vn>
<bld>
<plugins>
<plugin>
<gId>org.apache.maven.plugins</gId>
<aId>maven-compiler-plugin</aId>
<vn>1.1</vn>
<configuration>
<source>1.0</source>
<target>1.0</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</bld>
<dps>
<dp>
<gId>org.sk</gId>
<aId>sk-api</aId>
<vn>1.7.20</vn>
</dp>
<dp>
<gId>org.sk</gId>
<aId>sk-log</aId>
<vn>somevalue</vn>
</dp>
</dps>
</proj>
解决方案
您是否尝试使用模块 xmltodict 将该 xml 更改为 dict,然后再次将其更改为 xml?
这是一个替换dict上元素的小功能,当两个键相等时会出现问题,但是对于用不重复的键替换元素没关系,至少对我有用:
def changes_dict(self, tree, change):
"""Function that changes the values of a json with the keys given
:param tree: Json to be changed
:param change: Dictionary with the keys to be changed and the new values: {field1: value1, field2: value2,..., fieldN: valueN}"""
if isinstance(tree,(list,tuple)):
res = []
for subItem in tree:
result = self.changes_dict(subItem, change)
res.append(result)
return res
elif isinstance(tree,dict):
for nodeName in tree.keys():
subTree = tree[nodeName]
if nodeName in list(change.keys()):
tree[nodeName] = {'value': str(change[nodeName])}
change.pop(nodeName)
if not change:
break
else:
tree[nodeName] = self.changes_dict(subTree, change)
return tree
elif isinstance(tree, str):
return tree
我制作了这个程序并且性能很好:
# -*- coding: utf-8 -*-
import xmltodict, json
def changes_dict(tree, change, wordHelp):
"""Function that changes the values of a json with the keys given
:param tree: Json to be changed
:param change: Dictionary with the keys to be changed and the new values: {field1: value1, field2: value2,..., fieldN: valueN}
:param wordHelp: Word that must be in the values of the dict that contains the change"""
if isinstance(tree,(list,tuple)):
res = []
for subItem in tree:
result = changes_dict(subItem, change, wordHelp)
res.append(result)
return res
elif isinstance(tree,dict):
for nodeName in tree.keys():
subTree = tree[nodeName]
if nodeName in list(change.keys()) and wordHelp in list(tree.values()):
tree[nodeName] = {'value': str(change[nodeName])}
change.pop(nodeName)
if not change:
break
else:
tree[nodeName] = changes_dict(subTree, change, wordHelp)
return tree
elif isinstance(tree, str):
return tree
x = """
<proj>
<mV>4.0.0</mV>
<gId>com.test</gId>
<aId>console</aId>
<vn>1.0</vn>
<bld>
<plugins>
<plugin>
<gId>org.apache.maven.plugins</gId>
<aId>maven-compiler-plugin</aId>
<vn>1.1</vn>
<configuration>
<source>1.0</source>
<target>1.0</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
</plugins>
</bld>
<dp>
<gId>org.sk</gId>
<aId>sk-api</aId>
<vn>1.7.20</vn>
</dp>
<dp>
<gId>org.sk</gId>
<aId>sk-log</aId>
<vn>1.7.25</vn>
</dp>
</dps>
</proj> """
dicti = eval(json.dumps(xmltodict.parse(x)))
dicti_changed = changes_dict(dicti, {'vn': 'somevalue'}, 'sk-log')
print(xmltodict.unparse(dicti_changed))
问候
推荐阅读
- android - 进程 'command'/Users/rodrigovieira/Library/Android/sdk/ndk-bundle/ndk-build'' 以非零退出值 2 结束
- c++ - CGAL 将非流形 Nef_polyhedron_3 转换为三角形网格
- apache-spark - 如何在pyspark中读取多级json?
- jenkins - 没有这样的属性:类的 scm: Jenkins 版本中的 groovy.lang.Binding。2.107.2。
- python - 如何获取具有多个打印语句的 API 调用函数以在 Flask 中显示?
- sql-server - 基于连接字符串/环境的 SSMS 颜色选项卡
- android - 在 Android Auto Queue 中选择媒体项不执行任何操作
- php - Nginx:将子域重写到其中的文件夹和文件
- python - 如何将 Celery 任务从一台机器发送到另一台机器?
- webrtc - 边缘回声 webrtc