2

Pythonの初心者、さらにはxmlの初心者なので、我慢してください:)

以下のような構造の既存のxmlファイルがあります。<Zone>一致するノード、または指定したノードのクローンを作成したいと<name>.text == "Bill"思います。

ループして使用してelem.append(copy.deepcopy(---))みましたが、ノードを追加してループに追加することになりました。言うまでもなく、しばらくの間実行されました。

これをその場で簡単に行うことはできますか、それともすべてを別のファイルに書き込む必要がありますか?私はコードを追加しますが、それが壊れて物事を複雑にするのではないかと心配しています!

問題を明確にしたことを願っています。

<DBname>  
    <Level_1>  
        <Zone>  
            <name>Fred</name>  
            <att1>xxx</att1>  
            <att2>yyy</att2>  
        </Zone>  
        <Zone>  
            <name>Bill</name>  
            <att1>111</att1>  
            <att2>222</att2>  
        </Zone>  
        <Zone>  
            <name>Bob</name>  
            <att1>333</att1>  
            <att2>444</att2>  
        </Zone>  
    </Level_1>  
</DBname>  

OK私は解決策を考え出したかもしれませんが、コメント/改善は大歓迎です。

これは動作しません。追加された項目は「for」ループを詰め込みます。

from lxml import etree as ET
import copy

tree = ET.parse(xml_file)
root  = tree.getroot()
for elem in root:
    for source in elem:
        if source.find('name').text == "Bill":
            elem.append(copy.deepcopy(source))

これは機能しているように見えます:

from lxml import etree as ET
import copy

tree = ET.parse(xml_file)
root  = tree.getroot()
for elem in root:
    for zone in elem.findall('Zone'):
        if zone.find('name').text == "Bill":
            elem.append(copy.deepcopy(zone))
4

1 に答える 1

1

2 回目の試行は正しいようです。問題は、オブジェクトを反復しようとしている間にオブジェクトを変更していることです。

の場合、子ノードを遅延して反復してfor source in elemいるように見えるため、最後に到達する前に追加された新しいノードは反復に含まれます。を使用すると、その後の への変更の影響を受けない子孫の新しいリストを取得できます。lxmllxml.findallelem

現在、作業コードのセマンティクスが異なることに注意してください。子タグだけでなく、すべての子孫タグが検索されますZone。スキーマを考えると、これはおそらく問題ではありませんが、不要であることがすでにわかっている余分な作業です。

次のようにして、最初の試行を修正できます。

for source in list(elem):

これにより、子ノードの個別のリストが作成されるため、変更elemは安全で、ループには影響しません。

そして、明示的にループを s だけに制限したい場合Zone:

for source in list(elem.iter('Zone')):
于 2013-03-01T02:14:05.647 に答える