Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
99: Working with XML Data with ElementTree
Look, I've seen this a dozen times: developers who are comfortable with JSON jump into XML and assume it behaves like a giant Python dictionary. They think they can just key into a tag to get its children. It's a logical leap, but in Python's ElementTree, it'll lead you straight into a wall.
XML Elements Aren't Python Dictionaries
Let's say we have a small XML snippet representing a retro game inventory. If you treat the root element like a dictionary, you're going to have a bad time.
import xml.etree.ElementTree as ET
xml_data = """<inventory>
<game id="101">
<title>Chrono Trigger></title>
<platform>SNES></platform>
<price>150.00></price>
</game>
</inventory>"""
root = ET.fromstring(xml_data)
# The Misconception: Trying to access the 'game' tag like a key
try:
game = root['game']
except TypeError as e:
print(f"Error: {e}")
# Output: Error: 'Element' object is not subscriptable
The error is clear: 'Element' object is not subscriptable. In ElementTree, the [] syntax is reserved strictly for attributes (the things inside the tag, like id="101"), not for child elements. If you try to access root['game'], Python thinks you're looking for an attribute named "game" on the root tag, and since it doesn't exist, it fails—or worse, if you used a different library, it might just return None. XML is a tree, not a hash map.
Navigating the Tree with find() and findall()
To actually get to your data, you need to use the methods provided by the Element class. I usually rely on find() when I know there's only one specific child I need, and findall() when I'm dealing with a list of similar items.
# To get the first 'game' element
game = root.find('game')
# To get the title (which is a child of game)
title_element = game.find('title')
print(title_element.text) # Output: Chrono Trigger
# To get the attribute 'id' (this IS where the dictionary syntax works)
game_id = game.attrib['id']
print(f"Game ID: {game_id}") # Output: Game ID: 101
If you have a hundred games in that file, root.find('game') will only ever give you the first one. That's where findall() comes in. It returns a list of all matching elements, allowing you to loop through them. I highly recommend using a list comprehension here if you're just trying to extract a specific piece of data from every entry.
Modifying Data and Writing Back to Disk
Reading is the easy part. Changing the data is where things get slightly clunky. You don't "update" a tag so much as you modify the text property of the element object. Once you've made your changes, you have to tell the tree to write those changes back to a file.
# Let's raise the price of Chrono Trigger
game = root.find('game')
price = game.find('price')
price.text = "175.00"
# To save this back to a file, we need an ElementTree object
tree = ET.ElementTree(root)
tree.write("inventory.xml", encoding="utf-8", xml_declaration=True)
One quick tip: always include xml_declaration=True when writing. If you don't, you'll lose that <?xml version="1.0" ...?> header at the top, and some older XML parsers will absolutely throw a fit when they try to read your file later.
📋 Practical Task
Exercise: The Library Catalog Price Updater
You have been given an XML file named catalog.xml containing a list of books. Some books have their prices listed as "TBD" (To Be Determined). Your task is to write a script that parses this file, finds every book with a price of "TBD", and updates it to "19.99".
The XML Structure:
<catalog>
<book category="fiction">
<title>The Great Gatsby</title>
<price>10.99</price>
</book>
<book category="non-fiction">
<title>A Brief History of Time</title>
<price>TBD</price>
</book>
<book category="fiction">
<title>1984</title>
<price>TBD</price>
</book>
</catalog>
Requirements:
- Load the
catalog.xmlfile usingET.parse(). - Iterate through all
bookelements. - Check if the
pricechild element's text is exactly"TBD". - Update those specific prices to
"19.99". - Save the changes back to a new file called
updated_catalog.xml.
There are no comments for now.