SyntaxStudy
Sign Up
XML DOM Parsing with Python xml.etree.ElementTree
XML Beginner 1 min read

DOM Parsing with Python xml.etree.ElementTree

Python's standard library includes the xml.etree.ElementTree module, which provides a lightweight DOM-like API for parsing and creating XML documents. It represents the XML document as a tree of Element objects. Each Element has a tag (the element name in Clark notation for namespaced documents), a dict of attrib for attributes, a text property for the text before the first child, a tail property for text after the element's closing tag, and a list-like interface for accessing child elements. The two primary parse functions are ET.parse() which reads from a file and returns an ElementTree object, and ET.fromstring() which parses an XML string and returns the root Element directly. Searching is done with find() (returns the first matching element or None), findall() (returns a list of all matching elements), and findtext() (returns the text content of the first match). All three accept XPath subsets — limited to basic path expressions and predicates. For modifying and serializing XML, ElementTree provides Element construction functions, ET.SubElement() for adding children, and ET.tostring() or tree.write() for serialization. The xml_declaration parameter and the encoding parameter control whether an XML declaration is included in the output. For production applications requiring full XPath 1.0, XSLT, or schema validation, the third-party lxml library is recommended as it wraps the libxml2 and libxslt C libraries.
Example
# Python: DOM parsing with xml.etree.ElementTree

import xml.etree.ElementTree as ET

# Parse from a string
xml_string = """<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book id="b001" category="fiction">
        <title>The Great Gatsby</title>
        <author>F. Scott Fitzgerald</author>
        <year>1925</year>
        <price>12.99</price>
    </book>
    <book id="b002" category="non-fiction">
        <title>Clean Code</title>
        <author>Robert C. Martin</author>
        <year>2008</year>
        <price>35.00</price>
    </book>
</library>"""

root = ET.fromstring(xml_string)

# Iterate over all book elements
for book in root.findall('book'):
    book_id  = book.get('id')
    category = book.get('category')
    title    = book.findtext('title')
    author   = book.findtext('author')
    year     = book.findtext('year')
    price    = book.findtext('price')
    print(f'[{book_id}] {title} by {author} ({year}) — ${price} [{category}]')

# Modify: add a new book and serialize back to XML
new_book = ET.SubElement(root, 'book')
new_book.set('id', 'b003')
new_book.set('category', 'reference')
ET.SubElement(new_book, 'title').text  = 'XML in a Nutshell'
ET.SubElement(new_book, 'author').text = 'Elliotte Rusty Harold'
ET.SubElement(new_book, 'year').text   = '2004'

# Serialize (ET.indent available in Python 3.9+)
ET.indent(root, space='    ')
output = ET.tostring(root, encoding='unicode', xml_declaration=False)
print(output[:200])