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

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to