Empusas
Empusas

Reputation: 412

Python lxml change xml object child text attribute

I have an xml that I parsed with objectify from an API output and i refer to it as "result" variable. Now I want o keep the object, but only change the text file and give it back to the API to update the element.

<field xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="multi_text_area">
  <id>1754</id>
  <name>Devices under maintenance</name>
  <read_only>false</read_only>
  <text_area>
    <text>defwhanld12x</text>
  </text_area>
</field>

When I try to change the text I get like this, I get an error:

result.text_area.text = 'This is a test'

TypeError: attribute 'text' of 'ObjectifiedElement' objects is not writable

I also tried to strip the element and recreate it as the lxml documentation says that you can not change an object.

etree.strip_elements(result, 'text')
etree.SubElement(result.text_area, 'text').text = 'This is just a test'

But get a similar error:

TypeError: attribute 'text' of 'StringElement' objects is not writable

Upvotes: 2

Views: 1914

Answers (1)

har07
har07

Reputation: 89285

This is because your element is named text. text is also used by lxml.objectify to store inner text of an element, and that's how the conflict happened. When you do result.text_area.text, it is interpreted as trying to access the inner text of text_area, instead of accessing child element named text. You can avoid this conflict by accessing the text element as follow :

result.text_area['text'] = 'This is a test'

UPDATE :

The above turned out to be replacing the entire <text> element with the new text, which end up as an element in the form you mentioned in the comment below :

<text xmlns:py="http://codespeak.net/lxml/objectify/pytype" 
      py:pytype="str">This is a test</text>

The correct way to update inner text of text element would be using _setText(), as mentioned in this other answer :

result.text_area['text']._setText('This is a test')

Upvotes: 2

Related Questions