Python在循环遍历字典和替换xml属性时遇到麻烦

2024-09-29 23:16:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我在遍历下面的Python列表并用所有ADSType值替换xml属性时遇到问题

Python字典

{'ADSType': ['HS11N', 'HS11V'], 'Type': ['Bond', 'Cash']}

XML

我想用ADS值替换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")

如何遍历列表、提取值、动态地输入replace方法和更新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>

Tags: getxmlreqstartdatendabcfreq
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的索引。然后将其用于数据类型列表中的索引

未添加任何XML验证以确保要替换的属性存在。我也没有考虑多个“fld”标签。在平板电脑上写东西很难添加更健壮的代码。当我回到笔记本电脑的时候,我会尝试用一些不那么快和肮脏的东西来更新

您不需要替换任何内容,只需使用新值来覆盖:

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")

这正是你想要的,尽管我不知道完整的格言如何符合你的问题:

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'])

相关问题 更多 >

    热门问题