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

特に再帰的なソリューションが必要な場合は、@JohnMachinの答えで問題ありません。しかし、あなたはそれを繰り返し行うことができます:

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 に答える