1. Lo que debes saber antes de leer XML con Python
¿En qué situaciones se maneja XML con Python?
Python es un lenguaje de programación de propósito general usado en muchos ámbitos, y entre ellos la “lectura de archivos XML” es una de las técnicas frecuentemente utilizadas en el procesamiento de datos. En particular, en los siguientes casos se necesita leer XML con Python.
- Quiero analizar datos XML obtenidos de una API web
- Quiero procesar archivos XML exportados desde otros sistemas
- Quiero leer XML que se utiliza como archivo de configuración (config)
XML permite expresar claramente la jerarquía y el significado de los datos mediante una estructura de etiquetas, por lo que se utiliza en diversas industrias. Con Python, es posible leer, transformar y analizar fácilmente estos datos XML.
¿Qué es XML? Repaso rápido
XML (Extensible Markup Language) es un lenguaje de marcado que permite definir de forma flexible la estructura de los datos. Tiene una estructura similar a HTML, pero su uso es diferente. Mientras que HTML se utiliza para la presentación (visual), XML es un formato para describir la estructura y el significado de los datos.
Por ejemplo, el siguiente formato es un XML típico:
<book>
<title>Introducción a Python</title>
<author>Tarō Yamada</author>
<price>2800</price>
</book>
Para leer y utilizar datos en este formato con Python, es necesario usar una biblioteca especializada.
Bibliotecas para leer XML en Python
Python ofrece varias opciones, tanto en la biblioteca estándar como en bibliotecas externas, para leer XML. Las más representativas son las siguientes.
xml.etree.ElementTree
(biblioteca estándar)xml.dom.minidom
(biblioteca estándar)lxml
(biblioteca externa, compatible con XPath y validación)
En este artículo explicaremos de manera clara, con ejemplos de código, cómo leer archivos XML con Python usando estas bibliotecas. Incluso los principiantes podrán seguirlo, ya que introduciremos los conceptos desde lo básico de forma cuidadosa, así que no se preocupe.
2. Conceptos básicos para leer XML con Python
Lectura de archivos XML con ElementTree
Primero, veamos cómo leer usando ElementTree
con un archivo XML real.
XML de ejemplo (sample.xml):
<books>
<book>
<title>Introducción a Python</title>
<author>Taro Yamada</author>
<price>2800</price>
</book>
<book>
<title>El futuro de la IA</title>
<author>Ichiro Suzuki</author>
<price>3500</price>
</book>
</books>
Código Python:
import xml.etree.ElementTree as ET
# Lectura del archivo XML
tree = ET.parse('sample.xml')
root = tree.getroot()
# Verificar la etiqueta del elemento raíz
print(f"Elemento raíz: {root.tag}")
# Procesar cada elemento book en bucle
for book in root.findall('book'):
title = book.find('title').text
author = book.find('author').text
price = int(book.find('price').text)
print(f"Título: {title}, Autor: {author}, Precio: {price}¥")
Resultado de la ejecución:
Elemento raíz: books
Título: Introducción a Python, Autor: Taro Yamada, Precio: 2800 yen
Título: Futuro de la IA, Autor: Ichiro Suzuki, Precio: 3500 yen
De esta manera, ElementTree.parse()
lee el archivo XML, getroot()
obtiene el elemento raíz, y find()
o findall()
extraen los elementos necesarios; este es el flujo básico.
Cómo leer XML desde una cadena
A veces el XML se proporciona como una cadena en lugar de un archivo. En ese caso, se analiza usando ET.fromstring()
.
Ejemplo:
xml_data = '''
<user>
<name>Sagawa Shota</name>
<email>sagawa@example.com</email>
</user>
'''
root = ET.fromstring(xml_data)
name = root.find('name').text
email = root.find('email').text
print(f"Nombre: {name}, Correo: {email}")
De manera similar, se pueden obtener los subelementos necesarios del elemento raíz con find()
y extraer sus valores.
Obtención de atributos y manejo de texto
Los elementos XML pueden tener atributos definidos en la etiqueta. En Python, se puede acceder a ellos con .attrib
.
Ejemplo (XML con atributos):
<user id="101">
<name>Sagawa Shota</name>
</user>
Código Python:
root = ET.fromstring('''
<user id="101">
<name>Shota Sagawa</name>
</user>
''')
print(f"ID de usuario: {root.attrib['id']}")
3. Introducción a otras bibliotecas de análisis XML
minidom: Biblioteca estándar basada en DOM
xml.dom.minidom
es un analizador XML incluido por defecto en Python, que permite manejar XML según la especificación DOM (Document Object Model) del W3C.
Puede dar la impresión de ser un poco más difícil de usar que ElementTree
, pero resulta útil cuando se desea manipular detalladamente los tipos y la estructura de los nodos.
Ejemplo:
from xml.dom import minidom
xml_data = '''
<user>
<name>Sagawa Shota</name>
<email>sagawa@example.com</email>
</user>
'''
dom = minidom.parseString(xml_data)
name = dom.getElementsByTagName('name')[0].firstChild.nodeValue
email = dom.getElementsByTagName('email')[0].firstChild.nodeValue
print(f"Nombre: {name}, Correo: {email}")
Características y ventajas:
- Acceso fácil a la estructura detallada de los nodos
- Los atributos y tipos de nodos hijos están claramente clasificados
- Facilidad para formatear y emitir XML (pretty print)
Desventajas:
- El código tiende a ser redundante
- No es adecuado para procesar XML a gran escala (alto consumo de memoria)
lxml: Biblioteca externa rápida y potente
lxml
es un analizador XML rápido implementado en C, que también soporta funciones avanzadas de XML como XPath y XSLT. Proporciona una API similar a ElementTree
, por lo que el costo de aprendizaje es bajo.
Método de instalación:
pip install lxml
Uso básico:
from lxml import etree
xml_data = '''
<books>
<book>
<title>Python Práctico</title>
<price>3000</price>
</book>
</books>
'''
root = etree.fromstring(xml_data)
title = root.xpath('//book/title/text()')[0]
price = root.xpath('//book/price/text()')[0]
print(f"Título: {title}, Precio: {price}yen")
Características y ventajas:
- Posibilidad de búsquedas flexibles gracias a XPath
- Adecuado para procesar grandes volúmenes de XML rápidamente
- Compatibilidad con HTML, útil también para scraping
Desventajas:
- Requiere instalación de una biblioteca externa
- Se necesita una pequeña curva de aprendizaje inicial (XPath, etc.)
Resumen de cómo elegir la biblioteca
Biblioteca | Características | Casos adecuados |
---|---|---|
ElementTree | Disponible en la biblioteca estándar, permite lectura y escritura básicas | Lectura de XML de pequeña y mediana escala |
minidom | Fuerte en operaciones DOM y excelente en salida formateada | Cuando se desea manipular detalladamente la estructura de los nodos |
lxml | Rápido, compatible con XPath, alta flexibilidad | Para datos a gran escala y búsquedas avanzadas |

4. Código de ejemplo práctico
En esta sección se presenta de forma práctica el procesamiento de lectura de XML con Python, acercándolo a situaciones reales de negocio y procesamiento de datos. Concretamente, se muestran ejemplos de código que cubren patrones comunes como “Iteración de múltiples nodos”, “Filtrado por condición” y “Exportación a archivo XML”, entre otros.
Iteración de múltiples nodos
Si dentro del XML se repiten datos con la misma estructura (por ejemplo, varios elementos ), se utiliza
findall()
para realizar un bucle.
XML de ejemplo:
<books>
<book>
<title>Introducción a Python</title>
<author>Taro Yamada</author>
<price>2800</price>
</book>
<book>
<title>El futuro de la IA</title>
<author>Ichiro Suzuki</author>
<price>3500</price>
</book>
</books>
Código Python (usando ElementTree):
import xml.etree.ElementTree as ET
tree = ET.parse('books.xml')
root = tree.getroot()
for book in root.findall('book'):
title = book.find('title').text
author = book.find('author').text
price = int(book.find('price').text)
print(f"Título: {title}, Autor: {author}, Precio: {price}yen")
De esta manera, al acceder a cada elemento dentro del bucle, se pueden extraer y procesar datos del XML.
Filtrado por condición
A continuación, un procesamiento condicional para extraer solo los libros cuyo precio sea de 3000 yenes o más.
Código Python:
for book in root.findall('book'):
price = int(book.find('price').text)
if price >= 3000:
title = book.find('title').text
print(f"高額本: {title}({price}円)")
De esta forma, combinando la sentencia if
, se pueden manejar solo los elementos que cumplan la condición deseada.
Exportación a archivo XML (guardado)
Es frecuente modificar el XML leído y guardarlo nuevamente como archivo.
Ejemplo de exportación:
# Crear nuevo elemento raíz
root = ET.Element('users')
# Añadir elementos hijos
user1 = ET.SubElement(root, 'user', attrib={'id': '1'})
ET.SubElement(user1, 'name').text = 'Sagawa Shota'
ET.SubElement(user1, 'email').text = 'sagawa@example.com'
# Guardar como estructura de árbol
tree = ET.ElementTree(root)
tree.write('users.xml', encoding='utf-8', xml_declaration=True)
Con esto se genera un archivo XML como el siguiente:
<?xml version='1.0' encoding='utf-8'?>
<users>
<user id="1">
<name>Sagawa Shota</name>
<email>sagawa@example.com</email>
</user>
</users>
Aplicación: extracción con XPath (lxml)
Si se está usando lxml
, es posible realizar búsquedas más flexibles y potentes.
from lxml import etree
tree = etree.parse('books.xml')
titles = tree.xpath('//book[price >= 3000]/title/text()')
for title in titles:
print(f"Título de libro caro: {title}")
Al aprovechar XPath, se pueden extraer datos de forma intuitiva incluso con condiciones complejas.
5. Errores comunes y soluciones
Al leer XML con Python, pueden ocurrir varios errores, como errores de sintaxis o problemas de codificación de caracteres. En esta sección se presentan los errores típicos que suelen atrapar a los principiantes y sus soluciones.
UnicodeDecodeError: fallo de lectura por diferencia de codificación
Detalle del error:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x93 in position 10
Causa:
Si el archivo XML está guardado con una codificación distinta a UTF-8 (por ejemplo Shift_JIS o UTF-16), Python no podrá decodificarlo correctamente y se producirá un error.
Solución:
Especifique explícitamente la codificación al leer el archivo.
with open('sample.xml', encoding='shift_jis') as f:
data = f.read()
import xml.etree.ElementTree as ET
root = ET.fromstring(data)
También es válido pasar directamente en modo binario a ElementTree.parse()
.
ParseError: sintaxis XML inválida
Detalle del error:
xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 3, column 15
Causa:
Ocurre cuando alguna etiqueta del archivo XML no está cerrada, caracteres especiales (p.ej. &
) no están escapados, o hay errores de sintaxis.
Solución:
- Identificar la línea y columna correspondientes a partir del mensaje de error
- Usar el editor para formatear y revisar errores de sintaxis en el XML
- Convertir caracteres especiales (p.ej.
&
→&
)
Ejemplo: XML incorrecto
<note>
<text>5 & 3</text>
</note>
Después de la corrección:
<note>
<text>5 & 3</text>
</note>
NoneType Attribute Error: acceso a elemento inexistente
Detalle del error:
AttributeError: 'NoneType' object has no attribute 'text'
Causa:
Si la etiqueta especificada no existe en el XML, find()
devuelve None
y al acceder directamente a .text
se produce un error.
Solución:
Compruebe si el elemento existe antes de obtener su valor.
title_elem = book.find('title')
if title_elem is not None:
title = title_elem.text
else:
title = 'Título desconocido'
También, si usa Python 3.8 o superior, puede emplear el operador walrus (:=
) para escribir de forma concisa.
if (title_elem := book.find('title')) is not None:
print(title_elem.text)
XML file corrupto o vacío
Síntomas:
- No se produce error, pero
getroot()
devuelveNone
findall()
no devuelve nada
Causa:
- El archivo XML está vacío (0 bytes)
- Los datos están truncados (fallo de descarga, etc.)
Solución:
- Verificar el tamaño y contenido del archivo
- Ejecutar una validación de sintaxis con una herramienta de validación XML
- Revisar el proceso de origen de descarga o generación
6. Preguntas frecuentes (FAQ)
En esta sección, explicamos de forma clara en formato Q&A las dudas y preocupaciones más frecuentes de los lectores que desean “leer XML con Python”. El contenido está pensado para resolver de antemano los puntos donde es fácil tropezar en el trabajo o el aprendizaje.
Q1. ¿Cómo manejar la codificación (charset) de los archivos XML?
A.
Los archivos XML normalmente incluyen una especificación de codificación en la parte superior, como la siguiente:
<?xml version="1.0" encoding="UTF-8"?>
Python’s ElementTree
y lxml
automáticamente leen esta declaración, pero si la codificación no coincide al abrir el archivo, se producirá un error.
En archivos XML en japonés, a veces se usan Shift_JIS
o EUC-JP
, por lo que es seguro especificar explícitamente la codificación de la siguiente manera:
with open('sample.xml', encoding='shift_jis') as f:
data = f.read()
Además, al usar lxml
el manejo de la codificación es más flexible.
Q2. ¿Qué hacer cuando procesar archivos XML gigantes causa falta de memoria?
A.
Si se carga un XML de gran tamaño de una sola vez, se despliega todo en la memoria, lo que puede hacer que el procesamiento sea lento o que se produzca un error.
En esos casos, es eficaz usar un “parser tipo iterador” que pueda leer de forma secuencial.
import xml.etree.ElementTree as ET
for event, elem in ET.iterparse('large.xml', events=('end',)):
if elem.tag == 'book':
print(elem.find('title').text)
elem.clear() # Liberar memoria
Con este método, solo se procesa la parte necesaria en orden, lo que ahorra memoria.
Q3. ¿Cuáles son los beneficios de usar XML en lugar de JSON?
A.
Hoy en día, muchas API utilizan JSON, pero XML también tiene sus propias fortalezas.
- Permite definir estrictamente la estructura jerárquica (DTD/XSD, etc.)
- Posibilidad de diferenciar atributos y elementos
- Fuerte orientación a documentos, adecuada para archivos de configuración e información estructurada
- En sistemas de empresas y gobiernos locales, XML sigue siendo dominante
En resumen, XML sobresale más en definir documentos estructurados que en ser leído por personas. Dependiendo del caso de uso, seguirá siendo relevante en el futuro.
Q4. ¿Cuál debería usar, lxml
o ElementTree
?
A.
Es conveniente elegir según los siguientes criterios:
Biblioteca | Casos adecuados |
---|---|
ElementTree | XML de pequeña‑mediana escala, cuando la biblioteca estándar es suficiente |
lxml | Cuando se desea usar XPath, se necesita alta velocidad o se manejan grandes volúmenes de datos |
Para principiantes se recomienda comenzar con ElementTree
, pero en casos que requieren velocidad de procesamiento y extracción flexible con XPath, lxml
es potente.
7. Resumen
En este artículo, hemos explicado “Cómo leer XML con Python” de forma que sea fácil de entender para principiantes y, al mismo tiempo, fácil de aplicar en entornos profesionales.
La lectura de XML con Python es sorprendentemente simple
Si utilizas la biblioteca estándar xml.etree.ElementTree
, puedes leer XML de inmediato sin preparación especial. Una vez que aprendas la sintaxis básica y los métodos (parse()
, find()
, findall()
, etc.), será fácil obtener y procesar los datos.
Es importante elegir la biblioteca adecuada según el caso de uso
- Procesamiento pequeño y simple:
ElementTree
- Operaciones detalladas de nodos y salida formateada:
minidom
- Procesamiento rápido y búsqueda XPath:
lxml
Cada una tiene sus ventajas y desventajas, así que elige según el tamaño y el propósito del XML que manejes.
Prepárate para los errores y problemas comunes
Incluso los errores en los que los principiantes suelen tropezar no serán un problema si comprendes sus causas y soluciones. En particular, los “diferentes juegos de caracteres”, los “errores de sintaxis” y la “verificación de existencia de elementos” son frecuentes.
XML sigue siendo una tecnología vigente
Aunque el uso de JSON ha aumentado recientemente, XML todavía se utiliza en muchos sistemas empresariales, gubernamentales y en intercambios de datos. Dominar el procesamiento de XML con Python se convierte en una habilidad útil en una amplia gama de campos.