python - Can I clone an xml node in place? -
bit of newbie python , more xml bear me:)
i have existing xml file construction below. want clone <zone>
node matches <name>.text == "bill"
or whatever specify.
i tried looping through , using elem.append(copy.deepcopy(---))
ended appending nodes got added loop - needless ran while!
can in place or have write file? add together code afraid mangled , complicate things!
hope i've made problem clear.
<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 may have worked out solution comments / improvements welcome.
this not work. appended items stuff "for" loop:
from lxml import etree et import re-create tree = et.parse(xml_file) root = tree.getroot() elem in root: source in elem: if source.find('name').text == "bill": elem.append(copy.deepcopy(source))
this appear work:
from lxml import etree et import re-create tree = et.parse(xml_file) root = tree.getroot() elem in root: zone in elem.findall('zone'): if zone.find('name').text == "bill": elem.append(copy.deepcopy(zone))
your sec effort looks correct. problem you're modifying object while trying iterate on it.
in case of for source in elem
, appears lxml
iterates on kid nodes lazily, new node added before lxml
reaches end included in iteration. using .findall
, new list of descendants isn't affected subsequent changes elem
.
note working code has different semantics now; find all descendant zone
tags, not children. given schema, doesn't matter, it's work know don't need.
you prepare first effort doing:
for source in list(elem):
this creates separate list of kid nodes, modifications elem
safe , won't impact loop.
and if want explicitly restrict looping zone
s:
for source in list(elem.iter('zone')):
python xml python-3.x deep-copy
No comments:
Post a Comment