我需要搜索element并用XML文件中的另一个值替换。替换只能在条件匹配的行发生。
我有以下xml文件。
/sbin/ip route|awk '/default/ { print $3 }'
下面是替换代码。
<?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
和sk-log
是vn.text
。我只需要在该特定行中将1.7.25
替换为1.7.25
。上面的代码对我不起作用。我该怎么办?
预期输出为
somevalue
答案 0 :(得分:0)
您是否尝试使用模块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
我制作了这个程序,并在perf上工作:
# -*- 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))
致谢
答案 1 :(得分:0)
使用BeautifulSoup
和find_next()
:
list_text.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>
然后:
from bs4 import BeautifulSoup
with open('list_test.xml','r') as f:
soup = BeautifulSoup(f.read(), "html.parser")
aid = soup.find_all('aid')
for s in aid:
if s.text == 'sk-log':
vn = s.find_next('vn')
print("Original Value: {}".format(vn.text))
vn.string = 'SomeValue'
print("Replaced value: {}".format(vn.text))
输出:
Original Value: 1.7.25
Replaced value: SomeValue
编辑:
要将其写入相同的xml文件,我们将使用soup.prettify()
:
from bs4 import BeautifulSoup
with open('list_test.xml','r') as f:
soup = BeautifulSoup(f.read(), features="lxml")
aid = soup.find_all('aid')
for s in aid:
if s.text == 'sk-log':
vn = s.find_next('vn')
print("Original Value: {}".format(vn.text))
vn.string = 'SomeValue'
print("Replaced value: {}".format(vn.text))
with open("list_test.xml", "w") as f_write:
f_write.write(soup.prettify())
输出:
<?xml vn="1.0" encoding="UTF-8"?>
<html>
<body>
<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>
</body>
</html>
答案 2 :(得分:0)
这是您需要的: 导入xml.etree.ElementTree作为ET
tree = ET.parse('test.xml')
root = tree.getroot()
aIdValue = "sk-log"
for elt in root.iter("dp"):
print("%s - %s" % (elt.tag, elt.text))
aId = elt.find("aId")
vn = elt.find("vn")
print(aId.text)
print(vn.text)
if (aId.text == aIdValue):
print("vn will be changed.")
elt.find("vn").text='1.8.0'
tree.write('test.xml', 'unicode')