Parsing XML Files with ElementTree
ET.fromstring() converts an XML string into a tree structure of Element objects, making the hierarchical data queryable.
Try it: XML Element Trees
How ET.fromstring() turns XML text into a tree of Elements (tag, attributes, .text), and how find(), findall() and iter() walk that tree along a path such as users/user.
How it works
- The parser reads start tags, text and end tags left to right, keeping a stack of open elements; each start tag becomes an Element that is a child of the element on top of the stack.
- Text before an element's first child becomes its .text (whitespace included); an end tag must match the open element or parsing stops with ParseError.
- findall(path) starts at the element it is called on (the root is not part of the path) and follows each path segment down one level of children.
- find(path) returns the first match or None; iter(tag) visits every element in document order, including the root.
- Reading .text, .tag or .get('attr') on each result gives the extracted values; reading an attribute from None raises AttributeError.
Default run (29 steps): ET.fromstring() receives 183 characters. The parser reads tags left to right and keeps a stack of open elements. … findall() returned a list of 2 elements; reading e.get('x') from each gives ['2', '7'].
Simplified: A small, hand-written XML parser for a subset: elements, attributes, text, self-closing tags, comments, CDATA, processing instructions and the five predefined entities plus numeric character references. DOCTYPE/DTDs and namespaces are not supported. Error messages follow Python's expat parser for these cases (column numbers can differ for non-ASCII documents). Paths support tags, *, ., //, [@attr], [@attr='v'], [tag] and [n].
Loading the simulation…
From Text to Structure
XML begins as text, but its opening and closing tags describe a hierarchy. ElementTree makes that hierarchy queryable in Python. The central operation is ET.fromstring(): it converts an XML string into a tree of Element objects. After conversion, you work with structured elements rather than treating the XML as one long string.
Conversion Step
What do you think happens?
What does ET.fromstring(data) return when data contains XML describing a person?
Reveal answer
It returns an Element object representing the root element of the XML tree. In the described example, the root is the person element.
The conversion changes the way the data is represented: tree refers to a structured Element object rather than the original XML string. That object represents the entire hierarchy beneath the root.
data = '<person><name>Chuck</name><phone>...</phone><email hide="yes">...</email></person>'
tree = ET.fromstring(data)- 1Before the conversion, data is an XML string.
- 2
ET.fromstring(data)parses that XML string. - 3After the conversion, tree is an Element object representing the person root and its child elements.
- data holds the XML string.
ET.fromstring(data)parses the string into an Element tree.- tree represents the root person element and its hierarchy.
The root Element represents the outermost XML element. In the example described by the source, the root is person, and the tree contains three child elements: name, phone, and email. The resulting tree object does not behave like a printed copy of the original string. Instead, you interact with it through ElementTree operations such as find(), .text, and .get().
Finding Nested Elements
Once the XML has become a tree, find() searches that tree for the first element matching a given tag name. Calling tree.find('name') searches from the tree represented by tree and retrieves the name element. Calling tree.find('email') retrieves the email element described in the example.
find() retrieves an element, not the element's text directly. After finding an element, use .text to read the content inside it or .get(attribute_name) to read one of its attributes.
Reading Element Data
name_text is 'Chuck'; hide_value is 'yes'.The .text property retrieves the text content inside an element. In the source example, tree.find('name').text returns Chuck. The .get(attribute_name) method retrieves the value of a named attribute. In that same example, tree.find('email').get('hide') returns yes.
Complete Extraction
Parse and extract person data
Convert an XML string describing a person into an Element tree, then retrieve the name text and the email hide attribute.
- 1Create the XML string
The XML string contains a person root with name, phone, and email child elements. The email element has a hide attribute.
- 2Parse the string
Pass the XML string to
ET.fromstring(). The returned Element represents the person root and its hierarchy. - 3Find the name element
Use
tree.find('name')to retrieve the first element matching the name tag. - 4Read the name text
Use .text on the found name element. The source example gives Chuck.
- 5Find the email element
Use
tree.find('email')to retrieve the email element. - 6Read the hide attribute
Use .get('hide') on the email element. The source example gives yes.
The XML string has become a structured tree, and the requested values are retrieved as the text Chuck and the attribute value yes.
data = '<person><name>Chuck</name><phone>...</phone><email hide="yes">...</email></person>'
tree = ET.fromstring(data)
name = tree.find('name').text
hidden = tree.find('email').get('hide')- 1data contains the XML text.
- 2tree receives the Element object returned by
ET.fromstring(data). - 3
tree.find('name')retrieves the name element, and .text retrieves Chuck. - 4
tree.find('email')retrieves the email element, and .get('hide') retrieves yes.
name: Chuck
hidden: yesCommon Parsing Mistakes
Common mistake Treating the result of ET.fromstring() as if it were still a plain string.
What it looks likeAfter tree = ET.fromstring(data), continuing to handle tree as raw XML text.
Why it failsThe conversion produces an Element object representing the root and its hierarchy.
Do this insteadUse tree methods and element access such as find(), .text, and .get().
Common mistake Expecting find() to return the text value directly.
What it looks likeUsing tree.find('name') as though it directly returned Chuck.
Why it failsfind()returns the matching element.Do this insteadUse tree.find('name').text to retrieve the element's text content.
Common mistake Using .text to retrieve an attribute.
What it looks likeUsing tree.find('email').text when the needed value is hide="yes".
Why it failsThe text property reads content inside the element, while attributes are retrieved with .get(
attribute_name).Do this insteadUse tree.find('email').get('hide') for the hide attribute.
Common mistake Assuming whitespace is automatically removed.
What it looks likeReading text that contains formatting spaces or line breaks.
Why it failsWhitespace in XML text is preserved.
Do this insteadUse .strip() when the extracted text needs whitespace cleaned.
Practice Check
Suppose an XML string has a person root, a name child containing Ada, and an email child with hide="no". Write the three operations that parse the string, retrieve the name text, and retrieve the hide attribute.
Hints
- Use
ET.fromstring()for the conversion. - Use
find('name')and then .text for the name. - Use
find('email')and then .get('hide') for the attribute.
- 1A reliable sequence is: parse the XML string with
ET.fromstring(), usefind()to retrieve the first matching element, use .text for content, and use .get(attribute_name) for attributes. Remember that the result of parsing is a hierarchical Element object, and that XML whitespace remains present unless you clean it with .strip().
Key Takeaways
ET.fromstring()converts an XML string into a tree of Element objects.- The returned root Element represents the outermost XML element and its hierarchy.
find()searches for the first element matching a tag name.- Use .text for element content and .get(
attribute_name) for attribute values. - XML whitespace is preserved, so use .strip() when cleaned text is needed.