mmj mmj - 4 months ago 34
Python Question

Python lxml: insert text at given position relatively to subelements

I'd like to build the following XML element (in order to customize figure number formatting):

<figcaption>
<span class="fignum">Figura 1.2</span> - Description of figure.
</figcaption>


but I don't know how to specify position of text. In fact, if I create the subelement before creating text,

import lxml.etree as et
fc = et.Element("figcaption")
fn = et.SubElement(fc, "span", {'class':'fignum'})
fn.text = "Figure 1.2"
fc.text = " - Description of figure."


I get an undesired result (text is positioned before subelement):

<figcaption>
- Description of figure.<span class="fignum">Figure 1.2</span>
</figcaption>


How can I specify position of text relatively to subelements?

Answer

You need to use the tail property of the span element:

from lxml import etree as et
fc = et.Element("figcaption")
fn = et.SubElement(fc, "span", {'class':'fignum'})
fn.text = "Figure 1.2"
fn.tail = " - Description of figure."

print(et.tostring(fc))
b'<figcaption><span class="fignum">Figure 1.2</span> - Description of figure.</figcaption>'

with ElementTree, elements have a text inside the element, and a tail after and outside the element.

With multiple children, the text of the parent is the text before the first child, all the other text inside the element will be assigned to the childrens' tail.

Some examples from another answer to this question which has since been deleted:

<elem>.text of elem</elem>.tail of elem
<elem>.text of elem<child1/><child2/></elem>.tail of elem
<elem>.text of elem<child1/>.tail of child1<child2/>.tail of child2</elem>.tail of elem
<elem>.text of elem<child1>.text of child1</child1>.tail of child1<child2/>.tail of child2</elem>.tail of elem
Comments