我无法在下面的Python列表中循环,并将xml属性替换为所有 ADSType 值。
Python词典
{'ADSType': ['HS11N', 'HS11V'], 'Type': ['Bond', 'Cash']}
XML
我想用XML替换XML中每一行的 sid 值。
<req Times="1" action="get" chunklimit="1000" lang="ENU" msg="1" rank="1" rnklst="1" runuf="0">
<flds>
<f end="2016-02-29" freq="m" i="bond(long) hff" sid="abc" start="2016-02-29" />
<f end="2016-02-29" freq="m" i="bond(short) ggg" sid="abc" start="2016-02-29" />
</flds>
<dat>
<r CalculationType="3" ForceCalculate="1" i="123" />
</dat>
</req>
到目前为止Python代码:
data_list = {'ADSType': ['HS11N', 'HS11V'], 'Type': ['Bond', 'Cash']}
xml_file = './test.xml'
tree1 = ET.ElementTree(file=xml_file)
root1 = tree1.getroot()
for x in root1.iter('flds'):
for y in x.iter('f'):
y.set('sid', y.get('sid').replace("123", "abc"))
# print(ET.tostring(root1).decode("UTF-8"))
print "test"
# print(ET.tostring(root1).decode("UTF-8"))
tree1.write("./test.xml")
我陷入困境,如何迭代列表,提取值,动态地输入替换方法并更新xml。请帮忙!以下是我想要实现的理想输出。
<req Times="1" action="get" chunklimit="1000" lang="ENU" msg="1" rank="1" rnklst="1" runuf="0">
<flds>
<f end="2016-02-29" freq="m" i="bond(long) hff" sid="HS11N" start="2016-02-29" />
<f end="2016-02-29" freq="m" i="bond(short) ggg" sid="HS11V" start="2016-02-29" />
</flds>
<dat>
<r CalculationType="3" ForceCalculate="1" i="123" />
</dat>
</req>
答案 0 :(得分:2)
您无需替换任何内容,只需将 set 与将覆盖的新值一起使用:
from xml.etree import ElementTree as ET
xml_file = "./test.xml"
tree = ET.parse(xml_file)
root1 = tree.getroot()
data_list = {'ADSType':['HS11N', 'HS11V'], 'Type': ['Bond', 'Cash']}
# make iterator so we just call next(sids) to pull each value
sids = iter(data_list['ADSType'])
for flds in root1.iter('flds'):
for f in flds.iter('f'):
# set to new value
f.set("sid", next(sids))
# write
tree.write("./test.xml")
这完全符合你的要求,虽然我不确定完整的dict如何适合你的问题:
的test.xml:
In [3]: !cat test.xml
<req Times="1" action="get" chunklimit="1000" lang="ENU" msg="1" rank="1" rnklst="1" runuf="0">
<flds>
<f end="2016-02-29" freq="m" i="bond(long) hff" sid="abc" start="2016-02-29" />
<f end="2016-02-29" freq="m" i="bond(short) ggg" sid="abc" start="2016-02-29" />
</flds>
<dat>
<r CalculationType="3" ForceCalculate="1" i="123" />
</dat>
</req>
运行代码:
In [4]: from xml.etree import ElementTree as ET
In [5]: xml_file = "./test.xml"
In [6]: tree = ET.parse(xml_file)
In [7]: root1 = tree.getroot()
In [8]: data_list = {'ADSType': iter(['HS11N', 'HS11V']), 'Type': iter(['Bond', 'Cash'])}
In [9]: sids = iter(data_list['ADSType'])
In [10]: for flds in root1.iter('flds'):
....: for f in x.iter('f'):
....: f.set("sid", next(sids))
....: tree.write("./test.xml")
....:
新的test.xml:
In [11]: !cat test.xml
<req Times="1" action="get" chunklimit="1000" lang="ENU" msg="1" rank="1" rnklst="1" runuf="0">
<flds>
<f end="2016-02-29" freq="m" i="bond(long) hff" sid="HS11N" start="2016-02-29" />
<f end="2016-02-29" freq="m" i="bond(short) ggg" sid="HS11V" start="2016-02-29" />
</flds>
<dat>
<r CalculationType="3" ForceCalculate="1" i="123" />
</dat>
</req>
如果你在多个fld中有多个f并希望循环这些值,请使用 itertools.cycle 代替iter:
from itertools import cycle
sids = cycle(data_list['ADSType'])
答案 1 :(得分:-2)
这是一种快速而肮脏的方式。
for x in root1.iter('flds'):
f = x.iter('f')
for idx,y in enumerate(x):
if y < len(f):
y.set('sid', y.get('sid').replace("abc",data_list['ADSType'][y]))
只需使用enumerate在XML中获取f的索引。然后将其用于data_list ADSType中的索引。
未添加任何XML验证以确保要替换的属性存在。我也没有考虑多个'flds'标签。在平板电脑上写这么难以添加更强大的代码。回到笔记本电脑时,我会尝试用更快速和更脏的东西进行更新