Chapters: JavaScript HTML & CSS JSON XML YAML ← Full TOC

← XML Index

🐍 Python xml — ElementTree, minidom, lxml — parse and generate XML

Python's built-in xml.etree.ElementTree handles most XML needs. For XPath 1.0, XSLT, and DTD validation, use lxml. For small documents or pretty-printing, use xml.dom.minidom.

📋 Reference

ItemSyntax / ValueDescription
ET.parseET.parse('file.xml') → ElementTreeParse XML file
ET.fromstringET.fromstring(xml_string) → ElementParse XML string to root Element
ET.tostringET.tostring(element, encoding='unicode') → strSerialize Element to string
tree.getroottree.getroot() → ElementGet root element
element.tagelement.tag → strElement tag name (with namespace)
element.textelement.text → strText content of element
element.tailelement.tail → strText after closing tag
element.attribelement.attrib → dictAll attributes as dictionary
element.getelement.get('attr', default) → strGet attribute value
element.setelement.set('attr', 'value')Set attribute value
element.findelement.find('tag') → ElementFind first matching child
element.findallelement.findall('tag') → [Element]Find all matching children
element.findtextelement.findtext('tag') → strGet text of first matching child
element.iterelement.iter('tag') → iteratorRecursively iterate matching elements
element.appendelement.append(child)Append child element
element.removeelement.remove(child)Remove child element
ET.SubElementET.SubElement(parent, 'tag', attrib={}) → ElementCreate and append child
ET.ElementET.Element('tag', attrib={}) → ElementCreate new element
ET.indentET.indent(element, space=' ')Pretty-print indent (Python 3.9+)
tree.writetree.write('out.xml', encoding='utf-8', xml_declaration=True)Write to file
minidom.parseStringminidom.parseString(xml_bytes).toprettyxml()Pretty-print XML
lxml.etree.parselxml.etree.parse(file)lxml — full XPath, XSLT, validation
lxml.xpathelement.xpath('//tag', namespaces={})lxml — XPath with namespaces

💡 Example

import xml.etree.ElementTree as ET
import xml.dom.minidom as minidom
from pathlib import Path

# ── 1. Parse XML ─────────────────────────────────────────────
xml_data = """<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student id="1001" status="active">
    <name>Alice Smith</name>
    <email>alice@mywebuniversity.com</email>
    <gpa>3.95</gpa>
    <courses>
      <course code="CS101" credits="3" grade="A">Python</course>
      <course code="CS201" credits="3" grade="A-">JavaScript</course>
      <course code="CS301" credits="4" grade="A+">Data Science</course>
    </courses>
  </student>
  <student id="1002" status="active">
    <name>Bob Jones</name>
    <email>bob@mywebuniversity.com</email>
    <gpa>3.72</gpa>
    <courses>
      <course code="CS101" credits="3" grade="B+">Python</course>
    </courses>
  </student>
</students>"""

root = ET.fromstring(xml_data)

# ── 2. Navigate & extract ─────────────────────────────────────
print("=== All students ===")
for student in root.findall('student'):
    sid    = student.get('id')
    name   = student.findtext('name')
    gpa    = float(student.findtext('gpa'))
    courses = student.findall('courses/course')
    credits = sum(int(c.get('credits',0)) for c in courses)
    print(f"  [{sid}] {name}  GPA={gpa}  Credits={credits}")

# ── 3. Filter & search ────────────────────────────────────────
print("\n=== GPA >= 3.9 ===")
for s in root.iter('student'):
    if float(s.findtext('gpa', '0')) >= 3.9:
        print(f"  {s.findtext('name')} — {s.findtext('gpa')}")

print("\n=== All A+ courses ===")
for c in root.iter('course'):
    if c.get('grade') == 'A+':
        print(f"  {c.text} (code={c.get('code')})")

# ── 4. Modify XML ─────────────────────────────────────────────
# Add new student
new_student = ET.SubElement(root, 'student', id='1003', status='active')
ET.SubElement(new_student, 'name').text   = 'Carol Davis'
ET.SubElement(new_student, 'email').text  = 'carol@mywebuniversity.com'
ET.SubElement(new_student, 'gpa').text    = '3.88'
courses_el = ET.SubElement(new_student, 'courses')
ET.SubElement(courses_el, 'course', code='CS101', credits='3', grade='A').text = 'Python'

# ── 5. Pretty-print & write ───────────────────────────────────
ET.indent(root, space='  ')  # Python 3.9+
output = ET.tostring(root, encoding='unicode', xml_declaration=False)
print("\n=== Pretty XML ===")
print('<?xml version="1.0" encoding="UTF-8"?>')
print(output[:600] + '...')

# Write to file
tree = ET.ElementTree(root)
tree.write('students_out.xml', encoding='utf-8', xml_declaration=True)
print("\nWritten to students_out.xml")

# ── 6. minidom pretty-print ───────────────────────────────────
raw = ET.tostring(root)
pretty = minidom.parseString(raw).toprettyxml(indent='  ')
print("\nminidom output (first 300 chars):")
print(pretty[:300])

Path('students_out.xml').unlink(missing_ok=True)
# python3 xml_demo.py

← XPath  |  🏠 Index  |  XSLT & XSD →