AI & Data

Working with XML Data

Module 2

Parsing and extracting data from XML documents using XPath and Python libraries for data analysis

<root> <item> <item> /root/item/*

How to handle XML?

XML = eXtensible Markup Language

Key point: XML is self-descriptive - the tags describe the data they contain.

XML as a Tree Structure

Every XML document forms a tree hierarchy (like folders on your computer):

XML Document = Tree of Nodes
<breakfast_menu> ROOT ELEMENT First <food> item 📦 <food> name Belgian Waffles price $5.95 calories 650 Second <food> item 📦 <food> name French Toast price $4.50 calories 450

XML: An Example

<breakfast_menu>
    <food>
        <name>Belgian Waffles</name>
        <price>$5.95</price>
        <description>Two of our famous Belgian Waffles with...</description>
        <calories>650</calories>
    </food>
</breakfast_menu>

XML: Targeting Elements with XPath

XPath is like a GPS for navigating XML documents:

XPath Navigation - Finding Data in XML
/breakfast_menu/food/name breakfast_menu 📦 food name → Selects all name elements //food Search anywhere food (all) → Finds all food elements at any depth /breakfast_menu/food[1] breakfast_menu food #1 → First food element only (index starts at 1)
/ = one level down  |  // = search anywhere  |  [1] = first item only

XML: Read a Document Using Python (Native Option)

Python has built-in XML support:

import xml.etree.ElementTree as xmlReader

# read from xml
tree = xmlReader.parse('menu.xml')
root = tree.getroot()

# iterate through elements
for food in root.findall('food'):
    name = food.find('name').text
    print(name)

XML: Read a Document Using Python (with lxml)

from lxml import etree

# read from xml
tree = etree.parse('menu.xml')
root = tree.getroot()
print(root)
Why lxml? It has more extensive support of XPath and better performance than the native library.

XML: Get Elements Using XPath

elems = root.findall('./food')
data = [[elem.find("./name").text,
         elem.find("./price").text
         ] for elem in elems]

print(data)
# [['Belgian Waffles', '$5.95'], ['French Toast', '$4.50']]

This creates a list of lists - perfect for DataFrame conversion!

XPath 101

./food[starts-with(./name/text(), 'Be')]
Exercise: Load this XML file in your Python environment, then do the same in Orange using the Python Script widget.

Bind XML Results to an Orange Data Table

It is possible to bind "raw data" in Orange tables:

from Orange.data import *

data = [
    ['green', 4, 1.2, 'apple'],
    ['orange', 5, 1.1, 'orange'],
    ['yellow', 4, 1.0, 'peach']
]

color = DiscreteVariable('color', values=set([row[0] for row in data]))
calories = ContinuousVariable('calories')
fiber = ContinuousVariable('fiber')
fruit = DiscreteVariable('fruit', values=set([row[3] for row in data]))

domain = Domain([color, calories, fiber], class_vars=fruit)
table = Table.from_list(domain, data)

XML Exercises with Orange

  1. Import menu.xml via Python Script widget
  2. Parse XML → create list of data rows
  3. Convert to Orange table → store in out_data
Complete XML → Orange Pipeline
XML Source menu.xml Raw XML file Python Script Widget 1. Parse XML lxml.etree etree.parse() 2. Extract data XPath queries .findall() 3. Create Table Orange.data out_data Orange Widgets Data Table View results Visualize Charts, stats

XML Exercises with Orange (Advanced)

Archive: ml.zip - ML articles in XML

Multi-File Processing Pipeline
ml.zip (extracted) article1.xml article2.xml article3.xml ... For Each File Parse XML etree.parse() Extract year, month title Add column topic = 'ML' Combine All Merge rows all_data.extend() Create DataFrame Table.from_list() Orange Data Table View all articles Timeline Articles over time
Tip: Use glob.glob("ml/*.xml") to list all XML files.

Questions?

Working with XML Data

Next: REST APIs and Web Services

Slide Overview