【问题标题】:Python trouble with looping through dictionary and replacing xml attributePython 循环遍历字典和替换 xml 属性的问题
【发布时间】:2016-09-22 20:56:49
【问题描述】:

我无法遍历下面的 Python 列表并将 xml 属性替换为所有 ADSType 值。

Python 字典

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

XML

我想将 XML 中每一行的 sid 值替换为 ADS 值。

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

【问题讨论】:

  • 为什么会有债券和现金? dict 是如何融入其中的?

标签: python xml loops dictionary


【解决方案1】:

您不需要替换任何东西,只需使用 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'])

【讨论】:

  • 谢谢!解决方案有效!我只是想了解这个问题。但是,当前 data_list 是从列表 ['HS11N', 'HS11V'] 中的另一个函数动态返回的。我想遍历列表并更新 xml。
  • 所以你有一个列表而不是字典?
  • 那么逻辑应该是一样的,只要做sids = iter(the_list) 并应用相同的逻辑,如果有多个并且你想继续循环使用 itertools.cycle 逻辑在答案的最后。
  • 没错。这有助于吨!非常感谢!
【解决方案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 即可获得 f 在 XML 中的索引。然后将其用于 data_list ADSType 中的索引。

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

【讨论】:

  • 我绝对尊重你的努力,但这对我学习没有帮助。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2022-09-22
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 2023-02-10
  • 1970-01-01
相关资源
最近更新 更多