How to set ElementTree Element text field in the constructor

10,854

Solution 1

The constructor doesn't support it:

class Element(object):
    tag = None
    attrib = None
    text = None
    tail = None

    def __init__(self, tag, attrib={}, **extra):
        attrib = attrib.copy()
        attrib.update(extra)
        self.tag = tag
        self.attrib = attrib
        self._children = []

If you pass text as a keyword argument to the constructor, you will add a text attribute to your element, which is what happened in your second example.

Solution 2

The constructor does not allow for it because they thought that it would be improper to have every foo=bar add an attribute except for the random two: text and tail

If you think this is a dumb reason to remove constructor comforts (as I do) then you can create your own element. I did. I have it as a subclass and added a parent parameter. This allows you to still use it with everything else!

Python 2.7:

import xml.etree.ElementTree as ET

# Note: for python 2.6, inherit from ET._Element
#       python 2.5 and earlier is untested
class TElement(ET.Element):
    def __init__(self, tag, text=None, tail=None, parent=None, attrib={}, **extra):
        super(TextElement, self).__init__(tag, attrib, **extra)

        if text:
            self.text = text
        if tail:
            self.tail = tail
        if not parent == None:   # Issues warning if just 'if parent:'
            parent.append(self)

Python 2.6:

#import xml.etree.ElementTree as ET

class TElement(ET._Element):
    def __init__(self, tag, text=None, tail=None, parent=None, attrib={}, **extra):
        ET._Element.__init__(self, tag, dict(attrib, **extra))

        if text:
            self.text = text
        if tail:
            self.tail = tail
        if not parent == None:
            parent.append(self)
Share:
10,854

Related videos on Youtube

Steve Schulist
Author by

Steve Schulist

Quantitative Financial Analyst at PIMCO.

Updated on June 04, 2022

Comments

  • Steve Schulist
    Steve Schulist almost 2 years

    How do I set the text field of of ElementTree Element from its constructor? Or, in the code below, why is the second print of root.text None?

    import xml.etree.ElementTree as ET
    
    root = ET.fromstring("<period units='months'>6</period>")
    ET.dump(root)
    print root.text
    
    root=ET.Element('period', {'units': 'months'}, text='6')
    ET.dump(root)
    print root.text
    
    root=ET.Element('period', {'units': 'months'})
    root.text = '6'
    ET.dump(root)
    print root.text
    

    Here the output:

    <period units="months">6</period>
    6
    <period text="6" units="months" />
    None
    <period units="months">6</period>
    6