Error Handling in Python
Although that string contains tags, nesting, and attributes, your Python code cannot conveniently search it as a tree until it has been parsed.
From Text to Structure
XML data often arrives from a web service, file, or another system as a flat string of characters. Although that string contains tags, nesting, and attributes, your Python code cannot conveniently search it as a tree until it has been parsed. ElementTree provides fromstring for converting the XML string into a hierarchical tree object.
The transformation has two important stages. First, ET.fromstring reads the XML text and builds an in-memory tree. The outermost tag becomes the root element, and nested tags become child elements. Second, methods such as find let your code search that hierarchy instead of scanning the original characters. This is the basic parse-then-search process for working with XML.
Tracing the Parse
In this example, xml_data is still only a string before parsing. After ET.fromstring(xml_data) runs, root refers to the tree's outermost person element. The nested name and email tags are represented as child elements. The XML's hierarchy has therefore become a structure that Python code can query.
fromstring does not merely return part of the original text. It builds a tree object representing the entire XML document, including its root, child elements, text content, and attributes.
Finding and Reading Elements
Once the tree exists, call find on an element to search for the first element matching a tag name. The returned value is an element object, not the text itself. To obtain the characters inside that element, use .text. To obtain an attribute, use .get('attribute_name').
Reading a Name and an Attribute
Given a parsed person tree, retrieve the text inside the name element and the hide attribute on the email element.
- 1Parse
Pass the XML string to ET.fromstring. The result is the root person element and its hierarchy.
- 2Find the name
Call
root.find('name'). The first matching name element is returned. - 3Read text
Access the returned element's .text property to obtain Ada.
- 4Find the email
Call
root.find('email')to obtain the email element. - 5Read the attribute
Call
email.get('hide')to retrieve the value associated with the hide attribute.
The extracted values are Ada and yes.
import xml.etree.ElementTree as ET
xml_data = "<person><name>Ada</name><email hide=\"yes\">ada@example.com</email></person>"
root = ET.fromstring(xml_data)
name_element = root.find("name")
email_element = root.find("email")
print(name_element.text)
print(email_element.get("hide"))- 1The import makes the ElementTree functions available through ET.
- 2The XML string is flat text before parsing.
- 3ET.fromstring creates the hierarchical tree.
- 4find returns an element object for the requested tag.
- 5The .text property contains the characters inside the element.
- 6The .get method retrieves the value of a named attribute.
- Imports ElementTree and gives it the short name ET.
- Stores XML containing a person, a name element, and an email element with a hide attribute.
- Converts the XML string into an Element tree and stores the root element.
- Finds the first name element below the root.
- Finds the first email element below the root.
- Reads the name element's text content.
- Reads the email element's hide attribute.
Ada
yesText and Attribute Data
An XML element can carry different kinds of information. The characters between an opening and closing tag are available through .text. Attribute values are stored separately and are retrieved by naming the attribute in .get(). In the generated example, Ada is the text of name, while yes is the value of the hide attribute on email.
| XML information | How to access it | Generated example |
|---|---|---|
| Characters inside an element | .text | Ada |
| Named attribute value | .get('attribute_name') | yes |
| The element itself | find('tag_name') | The name or email element object |
ElementTree separates the element object from the text and attribute values stored on or inside it.
Missing Matches and Exact Names
Common mistake Treating find as though it directly returns text.
What it looks likename = root.find("name")Why it failsfind returns an element object or None, not the characters inside the element.
Do this insteadUse name.text after confirming that the element was found.
Common mistake Using .get() to retrieve element text.
What it looks likename.get("text")Why it failsThe source distinguishes text content from attributes. Text is accessed with .text.
Do this insteadUse name.text for the characters inside the element, and .get('attribute_name') for an attribute.
Common mistake Changing the capitalization of a tag or attribute name.
What it looks likeroot.find("Name") when the XML tag is nameWhy it failsXML tag and attribute names are case-sensitive.
Do this insteadMatch the exact spelling used in the XML.
Common mistake Using a missing element without handling None.
What it looks likemissing = root.find("phone")Why it failsIf no matching element exists, find returns None.
Do this insteadHandle the None case before attempting to access element data.
Guided Practice
Given the XML string <person><name>Ravi</name><email hide="no">ravi@example.com</email></person>, describe the result of parsing it with ET.fromstring. Then identify which expression retrieves Ravi and which expression retrieves no from the hide attribute.
Hints
- The outermost person tag becomes the root element.
- Use find with the exact tag name.
- Use .text for characters inside a tag and .get('hide') for the named attribute.
What do you think happens?
What does root.find('email').get('hide') retrieve from <email hide="no">ravi@example.com</email>?
Reveal answer
no
find returns the email element, and get('hide') retrieves the value of its hide attribute. The address between the tags is the element's text and would be accessed with .text.
Key Takeaways
- 1ET.fromstring converts a flat XML string into a hierarchical Element tree.
- 2The outermost XML tag becomes the root element, with nested tags represented as child elements.
- 3find searches for the first element matching a tag name and returns an element object or None.
- 4Use .text for an element's text content and .get('
attribute_name') for an attribute value. - 5XML tag and attribute names are case-sensitive, and code must handle the None result when no match is found.
At a glance
- Parsing comes before searching: ET.fromstring turns XML text into a navigable tree.
- find locates the first matching element, but it returns an element object or None rather than a string.
- Read characters inside an element with .text and read named attributes with .get().
- Exact capitalization matters for XML tag and attribute names.
- Handle the None case when a requested element may not exist.