Inserting string before end tag of an XML

Question:

<elem1>
<elem2/>
<elem2 id="1234567"/>20,000 Leagues Under the Sea</elem1>

I’ve been trying to insert strings from list x, if the id provided matches with a list item using lxml. The problem being, I can’t seem to find a way to do make it go right before the end of parent tag </elem1>.
Example string:

<elem3><elem4>book, item</elem4></elem3>

Desired output:

<elem1>
<elem2/>
<elem2 id="1234567"/>20,000 Leagues Under the Sea<elem3><elem4>book, item</elem4></elem3></elem1>

.tail function can do the thing I want, but on the opposite side of the tag, not inside it. Simply appending string to .text of the element technically works, but it can’t display it due to, I imagine, <elem2/> tags at the beginning in some cases, and after such case it usually stops working in subsequent iterations of a loop.

Asked By: Thorwyn

||

Answers:

You need to count() the number of elements in the document, and insert(where, what) after that:

books = """<elem1>
  <elem2/>
  <elem2 id="1234567"/>
  20,000 Leagues Under the Sea
</elem1>
"""
doc = etree.fromstring(books)
newbies = """<elem3>
<elem4>book, item</elem4>
</elem3>
"""
elems = etree.fromstring(newbies)


destination = int(doc.xpath('count(//*)'))
#you need the int() because the output of count() is a float
#also remember that python counts from zero
doc.insert(destination,elems)
print(etree.tostring(doc).decode())

Output:

 <elem1>
  <elem2/>
  <elem2 id="1234567"/>
  20,000 Leagues Under the Sea
<elem3>
<elem4>book, item</elem4>
</elem3></elem1>
Answered By: Jack Fleeting
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.