我给出了一个XML文件,如下所示。
<?xml version="1.0" encoding="UTF-8"?>
<A value="?">
<B value="?">
<C value="10"/>
<C value ="20"/>
</B>
<B value="?">
<C value = "5" />
<C value = "10" />
</B>
</A>
如何将children节点的值相加以递归设置父节点?
<?xml version="1.0" encoding="UTF-8"?>
<A value="45">
<B value="30">
<C value="10"/>
<C value ="20"/>
</B>
<B value="15">
<C value = "5" />
<C value = "10" />
</B>
</A>
答案 0 :(得分:2)
以下代码在Python 3.1.3(显示)和Python 2.7.1(未显示)中保持不变。完成所有工作的功能与版本无关。您可能希望更改其他两个位(从文件解析而不是从字符串解析,导入其他一些ElementTree实现等)以适合您自己。
>>> xml_in = """
... <A value="?">
... <B value="?">
... <C value="10"/>
... <C value ="20"/>
... </B>
... <B value="?">
... <C value = "5" />
... <C value = "10" />
... </B>
... </A>
... """
>>> import xml.etree.ElementTree as et
>>> def updated_value(elem):
... value = elem.get('value')
... if value != '?': return int(value)
... total = sum(updated_value(child) for child in elem)
... elem.set('value', str(total))
... return total
...
>>> root = et.fromstring(xml_in)
>>> print("grand total is", updated_value(root))
grand total is 45
>>> import sys; nbytes = sys.stdout.write(et.tostring(root) + '\n')
<A value="45">
<B value="30">
<C value="10" />
<C value="20" />
</B>
<B value="15">
<C value="5" />
<C value="10" />
</B>
</A>
>>>
答案 1 :(得分:1)
如果您需要专门的递归解决方案,那么@John Machin's answer就可以了。但你可以迭代地做到这一点:
from xml.etree import cElementTree as etree # adjust it for your python version
for ev, el in etree.iterparse('you_file.xml'):
if el.get('value') == '?':
el.set('value', str(sum(int(n.get('value')) for n in el)))
print(etree.tostring(el))
<A value="45">
<B value="30">
<C value="10" />
<C value="20" />
</B>
<B value="15">
<C value="5" />
<C value="10" />
</B>
</A>