Search code examples
pythonlxmllxml.objectify

How to create an objectified element with text with lxml


I'd like to create an element tree (not parsing!) with lxml.objectify that might look like this:

<root>
  <child>Hello World</child>
</root>

My first attempt was to write code like this:

import lxml.objectify as o
from lxml.etree import tounicode
r = o.Element("root")
c = o.Element("child", text="Hello World")
r.append(c)
print(tounicode(r, pretty_print=True)

But that produces:

<root xmlns:py="http://codespeak.net/lxml/objectify/pytype" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" py:pytype="TREE">
  <child text="Hello World" data="Test" py:pytype="TREE"/>
</root>

As suggested in other answers, the <child> has no method _setText.

Apparently, lxml.objectifiy does not allow to create an element with text or change the text content. So, did I miss something?


Solution

  • From the doc and the answer you linked. You should use SubElement:

    r = o.E.root()    # same as o.Element("root")
    c = o.SubElement(r, "child")
    c._setText("Hello World")
    print(tounicode(r, pretty_print=True))
    
    c._setText("Changed it!")
    print(tounicode(r, pretty_print=True))
    

    Output:

    <root xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <child>Hello World</child>
    </root>
    
    <root xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <child>Changed it!</child>
    </root>