Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

1XML

XML (eXtensible Markup Language) es un lenguaje de marcado que define un conjunto de reglas para la codificación de documentos en un formato que es tanto legible por humanos como por máquinas. Fue diseñado para almacenar y transportar datos, y es ampliamente utilizado en aplicaciones web, servicios web y sistemas de intercambio de datos.

XML permite a los usuarios definir sus propias etiquetas y estructuras de datos, lo que lo hace muy flexible y adaptable a diferentes necesidades. A diferencia de HTML, que tiene un conjunto fijo de etiquetas predefinidas, XML permite crear etiquetas personalizadas que describen el contenido de manera más precisa.

XML es un estándar abierto mantenido por el World Wide Web Consortium (W3C) y es ampliamente utilizado en diversas aplicaciones, incluyendo:

1.1Estructura de un documento XML

Un documento XML está compuesto por varios elementos clave:

Prólogo
Es la parte inicial del documento que puede incluir una declaración XML y otras instrucciones, como la definición de la codificación de caracteres. La declaración XML es opcional pero recomendada, y suele verse así: <?xml version="1.0" encoding="UTF-8"?>.
Elementos
Son las unidades básicas de un documento XML y están delimitados por etiquetas de apertura y cierre. Por ejemplo, <nombre>Juan</nombre> es un elemento que contiene el texto “Juan”.
Atributos
Son pares clave-valor que proporcionan información adicional sobre un elemento. Se incluyen dentro de la etiqueta de apertura. Por ejemplo, <persona id="123"> tiene un atributo id con el valor “123”.
Contenido
Es el texto o los datos que se encuentran entre las etiquetas de apertura y cierre de un elemento.
Comentarios
Se pueden incluir comentarios en un documento XML utilizando la sintaxis <!-- Comentario -->.

El siguiente fragmento muestra un poema estructurado en XML

poema.xml
<?xml version="1.0" encoding="UTF-8"?>

<poema fecha="Abril de 1915" lugar="Granada">
	<titulo>Alba</titulo>
	<verso>Mi corazón oprimido</verso>
	<verso>siente junto a la alborada</verso>
	<verso>el dolor de sus amores</verso>
	<verso>y el sueño de las distancias. </verso>
</poema>

donde se pueden distinguir claramente los diferentes elementos:

y los atributos de poema

Como se puede observar XML permite estructurar la información en forma jerárquica, como si fuera un árbol, donde los elementos pueden contener otros elementos anidados. Un archivo XML bien formado debe cumplir con ciertas reglas, como tener un único elemento raíz que contenga todos los demás elementos, y todas las etiquetas deben estar correctamente cerradas y anidadas.

Los atributos en XML permiten agregar metadatos o información adicional a los elementos, lo que puede ser útil para describir propiedades o características específicas de los datos. Sin embargo, es importante usarlos con moderación y de manera coherente para evitar complicaciones en la interpretación del documento.

Árbol que representa la estructura del poema en XML.

Árbol que representa la estructura del poema en XML.

Árbol que representa la estructura del poema en XML.

Árbol que representa la estructura del poema en XML.

Existen varios sitios en internet que permiten visualizar el árbol asociado. Por ejemplo: Code Beautify.

En el ejemplo anterior, el elemento raíz es poema, que contiene como elementos hijos: titulo y varios elementos verso. El elemento poema también tiene dos atributos: fecha y lugar, que proporcionan información adicional sobre el poema.

Que un documento XML se pueda representar como un árbol simplifica la consulta y manipulación de los datos, ya que se pueden utilizar técnicas de recorrido de árboles para acceder a elementos específicos o extraer información relevante.

2XPath: XML Path Language

XPath (XML Path Language) es un lenguaje de consulta utilizado para navegar y seleccionar nodos en documentos XML. Proporciona una sintaxis para definir rutas que permiten localizar elementos, atributos y otros nodos dentro de la estructura jerárquica de un documento XML.

Permite describir caminos a través del árbol XML utilizando una notación similar a la de los sistemas de archivos. Por ejemplo, la expresión /poema/titulo selecciona el elemento titulo que es hijo directo del elemento raíz poema. Evaluar una expresión XPath es buscar elementos o atributos en un documento XML que coincidan con los criterios especificados en la expresión. El resultado son todos los nodos que cumplen con esos criterios.

Por ejemplo, la expresión //verso selecciona todos los elementos verso en el documento, independientemente de su posición en la jerarquía. La expresión //verso[text()="Mi corazón oprimido"] selecciona el elemento verso que contiene el texto exacto “Mi corazón oprimido”.

En los ejemplos a continuación usaremos el siguiente documento XML que representa una biblioteca con varios libros y autores.

biblioteca.xml
<?xml version="1.0" encoding="UTF-8"?>
<biblioteca>
  <libro>
    <titulo>La vida está en otra parte</titulo>
    <autor>Milan Kundera</autor>
    <fechaPublicacion año="1973" />
    <precio>305.50</precio>
  </libro>
  <revista>
    <titulo>Computer Gaming World</titulo>
    <editorial>Golden Empire Publications</editorial>
    <fechaPublicacion año="1981" />
    <precio>669.99</precio>
  </revista>
  <libro>
    <titulo>Pantaleón y las visitadoras</titulo>
    <autor fechaNacimiento="28/03/1936">Mario Vargas Llosa</autor>
    <fechaPublicacion año="1973" />
    <precio>214.48</precio>
  </libro>
  <libro>
    <titulo>Conversación en la catedral</titulo>
    <autor fechaNacimiento="28/03/1936">Mario Vargas Llosa</autor>
    <fechaPublicacion año="1969" />
    <precio>541.78</precio>
  </libro>
  <revista>
    <titulo>PC Users</titulo>
    <editorial>RedUsers</editorial>
    <fechaPublicacion año="2000" />
    <precio>220.50</precio>
  </revista>
</biblioteca>

2.1Expresiones XPath para seleccionar nodos

ExpresiónDescripción
/Si está al principio de la expresión, indica el nodo raíz, si no, indica “hijo”
//Camino. Permite seleccionar nodos en un camino descendiente a partir de la posición actual
.Nodo actual
..Padre del nodo actual
@nombre_atributoAtributo

Cada consulta XPath devuelve un conjunto de nodos que cumplen con los criterios especificados en la expresión. Se recomienda realizar pruebas en XPath Tester.

/biblioteca
Selecciona el nodo raíz biblioteca.
/biblioteca/libro
Selecciona todos los nodos libro que son hijos directos de biblioteca.
//autor
Selecciona todos los nodos autor en el documento, independientemente de su posición en la jerarquía.
/biblioteca//titulo
Selecciona todos los nodos titulo que son descendientes de biblioteca, sin importar cuántos niveles haya entre ellos. En este caso, selecciona los títulos de libros y revistas.
//libro/precio
Selecciona todos los nodos precio que son hijos directos de cualquier nodo libro.
//editorial/..
Selecciona el nodo padre de todos los nodos editorial, que en este caso son nodos revista.
//autor[@fechaNacimiento]
Selecciona todos los nodos autor que tengan un atributo fechaNacimiento.

2.2Predicados

Los predicados pueden ser usados para filtrar un conjunto de nodos en base a una condición dada.

Los predicados se escriben entre corchetes ([, ]). /biblioteca/libro[position() = 1] : Selecciona el primer nodo libro hijo de biblioteca.

/biblioteca/libro[1]
Equivalente a la expresión anterior, selecciona el primer nodo libro hijo de biblioteca.
/biblioteca/libro[last()]
Selecciona el último nodo libro hijo de biblioteca.
/biblioteca/libro[last() - 1]
Selecciona el penúltimo nodo libro hijo de biblioteca.
/biblioteca/libro[position() < 3]
Selecciona los dos primeros nodos libro hijos de biblioteca.
//autor[not(@fechaNacimiento)]
Selecciona todos los nodos autor que no tengan un atributo fechaNacimiento.
//autor[@fechaNacimiento="28/03/1936"]
Selecciona todos los nodos autor cuyo atributo fechaNacimiento tenga el valor “28/03/1936”.

2.3Selectores y comodines

ExpresiónResultado
*Todos los elementos en el nivel actual
@*Todos los atributos del nodo actual
text()El contenido de texto de un nodo
/biblioteca/*
Selecciona todos los elementos hijos directos de biblioteca.
/biblioteca//*
Selecciona todos los elementos descendientes de biblioteca.
//autor[@*]
Selecciona todos los elementos autor que tengan algún atributo.
node()
Selecciona todos los nodos del documento.
//titulo/text()
Selecciona el texto (no el nodo completo) de los títulos.

2.4Selección de varios caminos

El operador | es el operador de unión permite seleccionar distintos caminos en el documento.

//libro/titulo | //libro/precio
Selecciona todos los nodos titulo y todos los nodos precio hijos de libro |

2.5Comparaciones

OperadorDescripciónEjemplo
=Igualdadprecio = 541.78
!=Distintoprecio != 541.78
<Menor estrictoprecio < 500
<=Menor o igualprecio <= 541.78
>Mayor estrictoprecio > 500
>=Mayor o igualprecio >= 541.78
/biblioteca//libro[precio < 350]
Selecciona todos los nodos libro que tengan como hijo directo un elemento precio con valor menor a 350.
/biblioteca//libro[precio < 350]/titulo
Selecciona todos los nodos titulo hijos de nodos libro que tengan como hijo directo un elemento precio con valor menor a 350.

2.6Operadores

OperadorDescripciónEjemplo
+Suma6 + 4
-Sustracción6 - 4
*Multiplicación6 * 4
divDivisión8 div 4
orDisyunciónprecio = 541.78 or precio = 214.48
andConjunciónprecio > 300 and precio <= 541.78
modMódulo (resto de la división entera)5 mod 2
/biblioteca//libro[precio > 300 and precio <= 541.78]
Selecciona todos los nodos libro que tengan como hijo directo un elemento precio con valor mayor a 300 y menor o igual a 541.78.
/biblioteca//libro[precio = 541.78 or precio = 214.48]
Selecciona todos los nodos libro que tengan como hijo directo un elemento precio con valor igual a 541.78 o 214.48.
/biblioteca//libro[precio + 100 > 600]
Selecciona los nodos libro donde el valor del elemento precio sumado a 100 es mayor que 600.

3Recuperación de Información en XML

En el contexto de la búsqueda académica y profesional Manning et al., 2008, la recuperación de información sobre documentos XML se divide principalmente en dos tipos de consultas:

Consultas CO (Content-Only)
Tratan al XML como una colección de texto plano, ignorando las etiquetas para la búsqueda pero usándolas quizás para mostrar fragmentos de resultados.
Consultas CAS (Content-and-Structure)
Permiten al usuario especificar condiciones tanto sobre el contenido como sobre la estructura. Por ejemplo: “buscar libros sobre ‘Python’ donde el autor sea ‘Milan Kundera’”. XPath es la herramienta por excelencia para expresar este tipo de consultas.

3.1El modelo de árbol extendido

Para procesar estas consultas, los motores de búsqueda suelen modelar el XML como un árbol extendido donde cada nodo es una unidad indexable. Un desafío clave es decidir la granularidad del índice: ¿deberíamos indexar el libro completo, cada capítulo o cada párrafo? Esta decisión impacta directamente en la precisión y el recall del sistema.

4Características de XPath 2.0

XPath 2.0 introduce mejoras significativas sobre la versión 1.0, incluyendo un sistema de tipos más rico, soporte para secuencias, expresiones condicionales y cuantificadores, así como una amplia biblioteca de funciones.

4.1Funciones integradas

XPath 2.0 ofrece una gran cantidad de funciones para manipular cadenas, números, fechas y secuencias.

FunciónDescripciónEjemplo
count(nodos)Cuenta el número de nodos en una secuenciacount(//libro)
sum(nodos)Suma los valores numéricos de los nodossum(//precio)
avg(nodos)Calcula el promedio de los valoresavg(//precio)
min(nodos)Devuelve el valor mínimomin(//precio)
max(nodos)Devuelve el valor máximomax(//precio)
contains(s1, s2)Verdadero si s1 contiene s2contains(titulo, 'XML')
starts-with(s1, s2)Verdadero si s1 empieza con s2starts-with(titulo, 'A')
ends-with(s1, s2)Verdadero si s1 termina con s2ends-with(titulo, '.')
upper-case(s)Convierte la cadena a mayúsculasupper-case('hola')
string-length(s)Devuelve la longitud de la cadenastring-length('abc')
matches(s, regex)Verdadero si la cadena cumple con la expresión regularmatches('123', '^\d+$')

4.2Secuencias

En XPath 2.0, todo es una secuencia. Un valor simple es una secuencia de un solo elemento. Las secuencias se pueden construir con paréntesis y comas.

4.3Expresiones condicionales (if-then-else)

Permiten evaluar condiciones y devolver diferentes resultados.

if (@precio > 500) then 'Caro' else 'Barato'

4.4Cuantificadores (some y every)

Permiten verificar si alguno o todos los elementos de una secuencia cumplen una condición.

4.5Tablas de referencia rápida

Descargar la Hoja de Referencia de XPath 2.0 en PDF.

5XML y Python

Python ofrece varias bibliotecas para trabajar con XML, siendo las más comunes xml.etree.ElementTree (nativa), lxml y xml.dom.minidom.

Si bien xml.etree.ElementTree es parte de la biblioteca estándar, su soporte para XPath es limitado (solo soporta XPath 1.0 simplificado). Para utilizar todas las capacidades de XPath 2.0 (incluyendo funciones), utilizaremos la biblioteca elementpath en conjunto con xml.etree.ElementTree.

elementpath es una biblioteca de Python que implementa completamente el estándar XPath 2.0 (y versiones posteriores) para la navegación y consulta de documentos XML. Complementa a xml.etree.ElementTree al permitir el uso de expresiones XPath más complejas y potentes que las que soporta la implementación nativa de Python.

Para instalar elementpath, se puede usar pip:

pip install elementpath
from xml.etree import ElementTree
import elementpath

# Cargar el documento XML
tree = ElementTree.parse("../_static/code/xml/biblioteca.xml")
root = tree.getroot()

# Realizar una consulta XPath
# Seleccionar todos los títulos de libros
titulos = elementpath.select(root, "/biblioteca/libro/titulo/text()")

print("Títulos de libros:")
for titulo in titulos:
    print(titulo)

# Seleccionar todos los autores con fecha de nacimiento
autores_con_fecha = elementpath.select(root, "//autor[@fechaNacimiento]/text()")

print("Autores con fecha de nacimiento:")
for autor in autores_con_fecha:
    print(autor)

# Seleccionar libros con precio menor a 300
libros_baratos = elementpath.select( root, "/biblioteca/libro[precio < 300]/titulo/text()")

print("Libros con precio menor a 300:")
for libro in libros_baratos:
    print(libro)
Output
Títulos de libros:
La vida está en otra parte
Pantaleón y las visitadoras
Conversación en la catedral
Autores con fecha de nacimiento:
Mario Vargas Llosa
Mario Vargas Llosa
Libros con precio menor a 300:
Pantaleón y las visitadoras

Otro ejemplo: Calcular el precio total de los libros

# Calcular el precio total de todos los libros usando la función sum
# de XPath 2.0
total_precio = elementpath.select(root, "sum(/biblioteca/libro/precio)")

print(f"Precio total de todos los libros: {total_precio:.2f}")
Output
Precio total de todos los libros: 1061.76

5.1Ejemplos avanzados con XPath 2.0

A continuación, veremos cómo utilizar funciones avanzadas, cuantificadores y expresiones condicionales con elementpath.

# Funciones de cadena: starts-with
# Seleccionar libros cuyo título comienza con "La"
libros_la = elementpath.select(
    root, "/biblioteca/libro[starts-with(titulo, 'La')]/titulo/text()"
)

print("Libros que empiezan con 'La':")
for libro in libros_la:
    print(f"\t- {libro}")
Output
Libros que empiezan con 'La':
	- La vida está en otra parte
# Cuantificadores: some
# Verificar si hay algún libro con precio mayor a 500
hay_caros = elementpath.select(root, "some $x in //precio satisfies $x > 500")

print(f"¿Hay libros caros (>500)? {hay_caros}")
Output
¿Hay libros caros (>500)? True
# Cuantificadores: every
# Verificar si todos los precios son positivos
todos_positivos = elementpath.select(root, "every $x in //precio satisfies $x > 0")

print(f"¿Todos los precios son positivos? {todos_positivos}")
Output
¿Todos los precios son positivos? True
# Expresiones condicionales: if-then-else
# Categorizar libros según su precio
categorias = elementpath.select(
    root,
    "for $libro in /biblioteca/libro return "
    "concat($libro/titulo, ': ', "
    "if ($libro/precio > 500) then 'Caro' else 'Barato')",
)

print("Categorización de libros:")
for cat in categorias:
    print(f"- {cat}")
Output
Categorización de libros:
- La vida está en otra parte: Barato
- Pantaleón y las visitadoras: Barato
- Conversación en la catedral: Caro

5.2Sindicación de contenidos: RSS y Atom

La sindicación de contenidos es una forma de distribuir información actualizada de sitios web a usuarios que se han suscrito a ellos. Los dos formatos más populares para esto son RSS y Atom, ambos basados en XML.

RSS (Really Simple Syndication)

RSS es una familia de formatos de fuentes web estandarizados que se utilizan para publicar trabajos actualizados con frecuencia, como entradas de blogs, titulares de noticias, audio y vídeo. El formato RSS permite a los editores sindicar datos de forma automática. La versión actual es RSS 2.0.

Atom

Atom es un estándar más reciente, desarrollado como una alternativa a RSS para solucionar algunas de sus ambigüedades y limitaciones. Fue estandarizado por el IETF (RFC 4287). Atom suele ser más robusto y consistente en su estructura.

Comparación: RSS vs Atom

CaracterísticaRSS 2.0Atom 1.0
EstandarizaciónNo estandarizado formalmente (mantenido por Harvard)Estándar IETF (RFC 4287)
Fecha de publicaciónElemento <pubDate> (formato RFC 822)Elemento <updated> (formato ISO 8601)
ContenidoSolo soporta texto plano o HTML escapadoSoporta texto, HTML, XHTML y contenido binario (Base64)
Identificación<guid> (opcional)<id> (obligatorio y único)
Autor<author> (email del autor)<author> (estructura con nombre, email, uri)

Lectura de Feeds con Python

La biblioteca feedparser es la herramienta estándar en Python para analizar tanto feeds RSS como Atom de manera transparente.

Para instalar feedparser:

pip install feedparser
Ejemplo 1: Leyendo noticias (RSS)
import feedparser

# URL del feed RSS de Clarin
rss_url = "https://www.clarin.com/rss/lo-ultimo/"

# Parsear el feed
feed = feedparser.parse(rss_url)

print(f"Fuente: {feed.feed.title}")
print("Últimas noticias:")

for entry in feed.entries[:3]:
    print("-" * 80)
    print(f"Título: {entry.title}")
    print(f"Link: {entry.link}")
Output
Fuente: Clarin.com - Home - Lo último
Últimas noticias:
--------------------------------------------------------------------------------
Título: Cuba comienza a liberar presos después de anunciar un indulto para más de 2.000 personas
Link: https://www.clarin.com/mundo/cuba-comienza-liberar-presos-despues-anunciar-indulto-2000-personas_0_5E13AP7686.html
--------------------------------------------------------------------------------
Título: Es oficial: diez grandes empresas inyectarán 85 millones de dólares al fondo de innovación de Nueva Jersey
Link: https://www.clarin.com/estados-unidos/oficial-grandes-empresas-inyectaran-85-millones-dolares-fondo-innovacion-nueva-jersey_0_J4Jh8TGhQ5.html
--------------------------------------------------------------------------------
Título: Texas, un bastión conservador en EE.UU., es el segundo estado con mayor consumo de OnlyFans: cuántos millones gastaron en la plataforma en 2025
Link: https://www.clarin.com/estados-unidos/texas-bastion-conservador-eeuu-segundo-estado-mayor-consumo-onlyfans-millones-gastaron-plataforma-2025_0_pHMxNXh7Xq.html
Ejemplo 2: Leyendo Gmail (Atom)

Gmail proporciona un feed Atom de los correos no leídos. Dado que requiere autenticación, este ejemplo muestra cómo se estructuraría la petición (nota: por seguridad, Gmail requiere contraseñas de aplicación si tienes 2FA activado).

import feedparser

# Reemplazar con tus credenciales (usar contraseña de aplicación)
username = "tu_usuario@gmail.com"
password = "tu_contraseña_de_aplicacion"

# URL del feed Atom de Gmail
gmail_url = f"https://{username}:{password}@mail.google.com/mail/feed/atom"

# Parsear el feed
feed = feedparser.parse(gmail_url)

print(f"Correos no leídos en: {feed.feed.title}")
print(f"Cantidad: {feed.feed.fullcount}")

for entry in feed.entries[:3]:
    print("-" * 80)
    print(f"De: {entry.author}")
    print(f"Asunto: {entry.title}")
    print(f"Resumen: {entry.summary}")
References
  1. Manning, C. D., Raghavan, P., & Schütze, H. (2008). Introduction to Information Retrieval. Cambridge University Press. https://nlp.stanford.edu/IR-book/