Problem inserting an element where I want it using lxml

Stefan Behnel stefan_ml at behnel.de
Wed Jan 5 02:47:04 EST 2011


Alan Meyer, 05.01.2011 06:57:
> I'm having some trouble inserting elements where I want them
> using the lxml ElementTree (Python 2.6). I presume I'm making
> some wrong assumptions about how lxml works and I'm hoping
> someone can clue me in.
>
> I want to process an xml document as follows:
>
> For every occurrence of a particular element, no matter where it
> appears in the tree, I want to add a sibling to that element with
> the same name and a different value.
>
> Here's the smallest artificial example I've found so far
> demonstrates the problem:
>
> <foo>
> <whatever>
> <something/>
> </whatever>
> <bingo>Add another bingo after this</bingo>
> <bar/>
> </foo>
>
> What I'd like to produce is this:
>
> <foo>
> <whatever>
> <something/>
> </whatever>
> <bingo>Add another bingo after this</bingo>
> <bar/>
> </foo>

Looks trivial to me. ;)


> Here's my program:
>
> -------- cut here -----
> from lxml import etree as etree
>
> xml = """<?xml version="1.0" ?>
> <foo>
> <whatever>
> <something/>
> </whatever>
> <bingo>Add another bingo after this</bingo>
> <bar/>
> </foo>
> """
>
> tree = etree.fromstring(xml)
>
> # A list of all "bingo" element objects in the unmodified original xml
> # There's only one in this example
> elems = tree.xpath("//bingo")
>
> # For each one, insert a sibling after it
> bingoCounter = 0
> for elem in elems:
>     parent = elem.getparent()
>     subIter = parent.iter()

".iter()" gives you a recursive iterator that will also yield the 
"something" Element in your case, thus the incorrect counting. You only 
want the children, so you should iterate over the Element itself.


>     pos = 0
>     for subElem in subIter:
>         # Is it one we want to create a sibling for?
>         if subElem == elem:

There is an .index() method on Elements that does what you want to achieve 
here. However, the right way to do it is  to use ".addnext()".

http://codespeak.net/lxml/api/lxml.etree._Element-class.html

Stefan




More information about the Python-list mailing list