0

我得到了一个如下的 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>

如何对子节点的值求和以递归地设置父节点?

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

2 回答 2

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>
    >>>
于 2011-01-25T00:58:25.077 回答
1

如果您特别需要递归解决方案,那么@John Machin 的答案很好。但是你可以迭代地做到这一点:

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>
于 2011-01-25T03:05:28.907 回答