3

I asked a question about adding multiple elements a couple weeks ago and now I've run into a similar issue. I have to create some XML where I'll have the following:

<embossed>
   <line>Test Line</line>
   <line>Test Line 2</line>
   <line>Test Line 3</line>
</embossed>

I cannot figure out how to create the same element N times in a row with different text using the LXML objectify.Element() method. I tried this:

embossed = objectify.Element('embossed')
embossed.line = objectify.Element("line")
embossed.line = objectify.Element("line")

But I end up with only one "line" element inside the "embossed" element. Does anyone know how to do this? Thanks!

1 Answer 1

3

Just append the lines to embossed, instead:

embossed = objectify.Element('embossed')
embossed.append(objectify.Element('line'))
embossed.line[-1] = 'Test Line'
embossed.append(objectify.Element('line'))
embossed.line[-1] = 'Test Line 2'

Each lxml tree tag acts like a list, where any children are elements in the list. Simply appending new objectify.Element objects makes them children of the tag you append them to.

You can then reach each element of that list by using indexing; the -1 index is the last element, allowing us to set it's text.

The above code outputs:

>>> from lxml import objectify, etree
>>> embossed = objectify.Element('embossed')
>>> embossed.append(objectify.Element('line'))
>>> embossed.line[-1] = 'Test Line'
>>> embossed.append(objectify.Element('line'))
>>> embossed.line[-1] = 'Test Line 2'
>>> print etree.tostring(embossed, pretty_print=True)
<embossed xmlns:py="http://codespeak.net/lxml/objectify/pytype" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" py:pytype="TREE">
  <line py:pytype="str">Test Line</line>
  <line py:pytype="str">Test Line 2</line>
</embossed>
Sign up to request clarification or add additional context in comments.

4 Comments

How do you assign values to the line items then? I'm creating the XML from a flat file and need to assign each line a different value.
@MikeDriscoll: Simply manipulate them like you would any element. I've updated the answer; now I store the newly created line element to variable, set the text attribute, then append it to the parent embossed tag.
ah-ha! I think I must be running an old version of lxml as I couldn't find a "text" property to set or the SubElement method that the other fellow mentioned. Thanks!
@MikeDriscoll: Actually, I just learned that .text doesn't work on objectify elements. I've updated the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.