Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set ElementTree Element text field in the constructor

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
like image 871
Steve Schulist Avatar asked Aug 07 '13 02:08

Steve Schulist


People also ask

What is Etree in Python?

The xml.etree.ElementTree module implements a simple and efficient API for parsing and creating XML data. Changed in version 3.3: This module will use a fast implementation whenever available.

How do you parse an XML string in Python?

There are two ways to parse the file using 'ElementTree' module. The first is by using the parse() function and the second is fromstring() function. The parse () function parses XML document which is supplied as a file whereas, fromstring parses XML when supplied as a string i.e within triple quotes.

What does Etree parse do?

Parsing from strings and files. lxml. etree supports parsing XML in a number of ways and from all important sources, namely strings, files, URLs (http/ftp) and file-like objects. The main parse functions are fromstring() and parse(), both called with the source as first argument.


2 Answers

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.

like image 158
Blender Avatar answered Sep 27 '22 22:09

Blender


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)
like image 29
Cory-G Avatar answered Sep 27 '22 22:09

Cory-G