Procesamiento XML en Python: Guía para Gestión de Datos Interoperables
XML es un lenguaje portátil y de código abierto que permite desarrollar aplicaciones legibles por otras aplicaciones, independientemente del sistema operativo o lenguaje de desarrollo.
¿Qué es XML?
Extensible Markup Language (XML) es un lenguaje de marcado similar a HTML o SGML. Recomendado por el World Wide Web Consortium (W3C) y disponible como estándar abierto.
XML es extremadamente útil para rastrear cantidades pequeñas a medianas de datos sin requerir una base de datos SQL.
Arquitecturas y APIs de Parser XML
La biblioteca estándar de Python proporciona interfaces mínimas pero útiles para trabajar con XML.
Las dos APIs más básicas y usadas para datos XML son SAX y DOM:
Simple API for XML (SAX): Registras callbacks para eventos de interés y dejas que el parser recorra el documento. Útil para documentos grandes o limitaciones de memoria: parsea el archivo mientras lo lee del disco, sin almacenar todo en memoria.
Document Object Model (DOM) API: Recomendación W3C donde el archivo completo se lee en memoria y se almacena en forma jerárquica (árbol) representando todas las características del documento XML.
SAX no procesa información tan rápido como DOM con archivos grandes. Por otro lado, usar DOM exclusivamente puede agotar recursos, especialmente con muchos archivos pequeños.
SAX es de solo lectura; DOM permite modificar el archivo XML. Como se complementan, no hay razón para no usar ambos en proyectos grandes.
Para nuestros ejemplos, usaremos un archivo XML simple movies.xml:
<collection shelf="New Arrivals"> <movie title="Enemy Behind"> <type>War, Thriller</type> <format>DVD</format> <year>2003</year> <rating>PG</rating> <stars>10</stars> <description>Talk about a US-Japan war</description> </movie> <movie title="Transformers"> <type>Anime, Science Fiction</type> <format>DVD</format> <year>1989</year> <rating>R</rating> <stars>8</stars> <description>A scientific fiction</description> </movie> <movie title="Trigun"> <type>Anime, Action</type> <format>DVD</format> <episodes>4</episodes> <rating>PG</rating> <stars>10</stars> <description>Vash the Stampede!</description> </movie> <movie title="Ishtar"> <type>Comedy</type> <format>VHS</format> <rating>PG</rating> <stars>2</stars> <description>Viewable boredom</description> </movie> </collection>
Parseo XML con API SAX
SAX es interfaz estándar para parseo XML orientado a eventos. Requiere crear tu propio ContentHandler subclasificando xml.sax.ContentHandler.
Tu ContentHandler maneja etiquetas y atributos específicos. Un objeto ContentHandler proporciona métodos para manejar eventos de parseo. Su parser llama a estos métodos mientras parsea.
Métodos startDocument e endDocument se llaman al inicio y fin del archivo XML. characters(text) recibe datos de caracteres.
Al inicio y fin de cada elemento, se llaman startElement(tag, attributes) e endElement(tag) (o startElementNS/endElementNS en modo namespace).
Método make_parser
Crea un nuevo objeto parser y lo retorna. Será del primer tipo de parser que el sistema encuentre.
xml.sax.make_parser([parser_list])
parser_list: Lista opcional de parsers a usar (deben implementar make_parser).
Método parse
Crea un parser SAX y lo usa para parsear un documento.
xml.sax.parse(xmlfile, contenthandler[, errorhandler])
Parámetros: xmlfile (archivo XML), contenthandler (objeto ContentHandler), errorhandler (opcional, objeto SAX ErrorHandler).
Método parseString
Crea parser SAX y parsea una cadena XML especificada.
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
Ejemplo Completo SAX
#!/usr/bin/python
import xml.sax
class MovieHandler(xml.sax.ContentHandler):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print("*****Movie*****")
title = attributes["title"]
print("Title:", title)
def endElement(self, tag):
if self.CurrentData == "type":
print("Type:", self.type)
elif self.CurrentData == "format":
print("Format:", self.format)
elif self.CurrentData == "year":
print("Year:", self.year)
elif self.CurrentData == "rating":
print("Rating:", self.rating)
elif self.CurrentData == "stars":
print("Stars:", self.stars)
elif self.CurrentData == "description":
print("Description:", self.description)
self.CurrentData = ""
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if __name__ == "__main__":
parser = xml.sax.make_parser()
parser.setFeature(xml.sax.handler.feature_namespaces, 0)
Handler = MovieHandler()
parser.setContentHandler(Handler)
parser.parse("movies.xml")
Parseo XML con API DOM
El Document Object Model (DOM) es una API multiplataforma del W3C para acceder y modificar documentos XML.
DOM es extremadamente útil para aplicaciones de acceso aleatorio. SAX solo permite ver una parte del documento a la vez.
Forma fácil de cargar documento XML y crear objeto minidom con xml.dom.minidom:
#!/usr/bin/python
from xml.dom.minidom import parse
import xml.dom.minidom
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
print("Root element:", collection.getAttribute("shelf"))
movies = collection.getElementsByTagName("movie")
for movie in movies:
print("*****Movie*****")
if movie.hasAttribute("title"):
print("Title:", movie.getAttribute("title"))
type = movie.getElementsByTagName('type')[0]
print("Type:", type.childNodes[0].data)
format = movie.getElementsByTagName('format')[0]
print("Format:", format.childNodes[0].data)
rating = movie.getElementsByTagName('rating')[0]
print("Rating:", rating.childNodes[0].data)
description = movie.getElementsByTagName('description')[0]
print("Description:", description.childNodes[0].data)
Resultado: Muestra cada película con sus detalles parseados del árbol DOM.
Para detalles completos, consulta la documentación estándar de Python SAX APIs y DOM APIs.
python
- Dominando tipos de datos en Python: Guía práctica
- Dominando operadores en Python: Guía completa
- Dominando la sentencia pass en Python: Guía práctica
- Dominando argumentos de funciones en Python: Posicionales, por palabra clave y por defecto
- Dominando Diccionarios en Python: Creación, Manipulación y Técnicas Avanzadas
- Dominando Iteradores en Python: Cómo Funcionan y Cómo Crear los Tuyos
- Explicación de Closures en Python: Cómo las Funciones Anidadas Capturan Variables
- Dominando datetime en Python: Guía Práctica de Fechas, Horas y Zonas Horarias
- Dominar time.sleep() en Python: Mejores Prácticas, Multihilo y Ejemplos Reales
- Visión general de Python: Lenguaje de alto nivel, legible, interactivo y orientado a objetos
- Números en Python: Entendiendo tipos de datos numéricos inmutables