Concepts / Error Handling in Python

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.

  • Programming

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.

XML stringperson with name and emailpersonroot elementnametext: Adaemailtext: ada@example.comfromstringchildchild
How does the nested structure written in the XML string become parent and child Element objects after ET.fromstring runs?

Tracing the Parse

python

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.

XML stringflat charactersElement treenested objectsET.fromstring
What changes when the XML string is passed to ET.fromstring?
Key point

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').

personnameAdaname elementfirst matching elementemailada@example.comchildchildfind('name')
How does find locate the specific element requested by a tag name?
Worked example

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.

  1. 1
    Parse

    Pass the XML string to ET.fromstring. The result is the root person element and its hierarchy.

  2. 2
    Find the name

    Call root.find('name'). The first matching name element is returned.

  3. 3
    Read text

    Access the returned element's .text property to obtain Ada.

  4. 4
    Find the email

    Call root.find('email') to obtain the email element.

  5. 5
    Read the attribute

    Call email.get('hide') to retrieve the value associated with the hide attribute.

Result

The extracted values are Ada and yes.

Code walkthrough
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"))
  1. 1
    The import makes the ElementTree functions available through ET.
  2. 2
    The XML string is flat text before parsing.
  3. 3
    ET.fromstring creates the hierarchical tree.
  4. 4
    find returns an element object for the requested tag.
  5. 5
    The .text property contains the characters inside the element.
  6. 6
    The .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.
Output
Ada
yes

Text 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.

emailada@example.comtexthideyes.text.get('hide')
What information belongs to an element's text content, and what information is stored separately as attribute key-value pairs?
XML informationHow to access itGenerated example
Characters inside an element.textAda
Named attribute value.get('attribute_name')yes
The element itselffind('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 like
    name = root.find("name")
    Why it fails

    find returns an element object or None, not the characters inside the element.

    Do this instead

    Use name.text after confirming that the element was found.

  • Common mistake

    Using .get() to retrieve element text.

    What it looks like
    name.get("text")
    Why it fails

    The source distinguishes text content from attributes. Text is accessed with .text.

    Do this instead

    Use 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 like
    root.find("Name") when the XML tag is name
    Why it fails

    XML tag and attribute names are case-sensitive.

    Do this instead

    Match the exact spelling used in the XML.

  • Common mistake

    Using a missing element without handling None.

    What it looks like
    missing = root.find("phone")
    Why it fails

    If no matching element exists, find returns None.

    Do this instead

    Handle the None case before attempting to access element data.

Guided Practice

EASY

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>?

  • ravi@example.com

  • email

  • no

  • None

Reveal answer
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

  1. 1
    ET.fromstring converts a flat XML string into a hierarchical Element tree.
  2. 2
    The outermost XML tag becomes the root element, with nested tags represented as child elements.
  3. 3
    find searches for the first element matching a tag name and returns an element object or None.
  4. 4
    Use .text for an element's text content and .get('attribute_name') for an attribute value.
  5. 5
    XML 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.

More concepts starting with E