Análisis XML en Python3


¿Qué es XML?

XML se refiere al Lenguaje de Marcado Extensible (eXtensible Markup Lxtensible Markup Language), un subconjunto del Lenguaje de Marcado Generalizado Estándar, que es un lenguaje de marcado utilizado para marcar documentos electrónicos y darles estructura.Tutorial de XML

XML está diseñado para transmitir y almacenar datos.

XML es un conjunto de reglas para definir marcado semántico; estas etiquetas dividen el documento en muchas partes y las identifican.

También es un meta-lenguaje de marcado, es decir, define un lenguaje sintáctico utilizado para definir otros lenguajes de marcado semánticos y estructurados relacionados con dominios específicos.


Análisis de XML en Python

Las interfaces de programación XML comunes son DOM y SAX. Estas dos interfaces procesan archivos XML de manera diferente y, por supuesto, se utilizan en diferentes situaciones.

Python tiene tres métodos para analizar XML: ElementTree, SAX y DOM.

1. ElementTree

xml.etree.ElementTree es un módulo de la biblioteca estándar de Python para procesar XML. Proporciona una API simple y eficiente para analizar y generar documentos XML.

2.SAX (simple API for XML )

La biblioteca estándar de Python incluye un analizador SAX. SAX utiliza un modelo controlado por eventos, procesa archivos XML activando eventos uno a uno durante el análisis y llamando a funciones de devolución de llamada definidas por el usuario.

3.DOM(Document Object Model)

Analizar los datos XML en un árbol en memoria y operar sobre XML mediante operaciones sobre el árbol.

Los archivos de ejemplo XML utilizados en este capítulomovies.xmlEl contenido es el siguiente:

Ejemplo

<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 schientific 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>

Python usa ElementTree para analizar XML

xml.etree.ElementTreees un módulo de la biblioteca estándar de Python para procesar XML.

A continuación se presentan algunos conceptos y usos clave del módulo xml.etree.ElementTree:

Objetos ElementTree y Element:

  • ElementTree: La clase ElementTree es una representación en árbol de un documento XML. Contiene uno o más objetos Element, que representan todo el documento XML.
  • Element: El objeto Element es la representación de un elemento en un documento XML. Cada elemento tiene una etiqueta, un conjunto de atributos y cero o más elementos hijos.

Analizar XML

Método fromstring(): Utilice el método fromstring() para convertir una cadena que contiene datos XML en un objeto Element:

Ejemplo

import xml.etree.ElementTree as ET

xml_string = '<root><element>Some data</element></root>'
root = ET.fromstring(xml_string)

Método parse(): Si los datos XML están almacenados en un archivo, puede utilizar el método parse() para analizar todo el documento XML:

tree = ET.parse('example.xml')
root = tree.getroot()

Recorrer el árbol XML

Método find(): Utilice el método find() para encontrar el primer elemento hijo con la etiqueta especificada:

title_element = root.find('title')

Método findall(): Utilice el método findall() para encontrar todos los elementos hijos con la etiqueta especificada:

book_elements = root.findall('book')

Acceder a los atributos y al contenido de texto de los elementos

attribAtributos: mediante el atributo attrib se puede acceder a los atributos del elemento:

price = book_element.attrib['price']

textTexto: mediante el atributo text se puede acceder al contenido de texto del elemento:

title_text = title_element.text

Crear XML

Constructor Element(): Use el constructor Element() para crear nuevos elementos:

new_element = ET.Element('new_element')

Función SubElement(): Use la función SubElement() para crear elementos hijos con la etiqueta especificada:

new_sub_element = ET.SubElement(root, 'new_sub_element')

Modificar XML

Modificar atributos y contenido de texto del elemento: modificar directamente los atributos attrib y text del elemento.

Eliminar elementos: use el método remove() para eliminar un elemento:

root.remove(title_element)

Lectura simple del contenido XML:

Ejemplo

import xml.etree.ElementTree as ET

# Definir una cadena XML
xml_string = '''
<bookstore>
    <book>
        <title>Introduction to Python</title>
        <author>John Doe</author>
        <price>29.99</price>
    </book>
    <book>
        <title>Data Science with Python</title>
        <author>Jane Smith</author>
        <price>39.95</price>
    </book>
</bookstore>
'''


# Usar ElementTree para analizar la cadena XML
root = ET.fromstring(xml_string)

# Recorrer el árbol XML
for book in root.findall('book'):
    title = book.find('title').text
    author = book.find('author').text
    price = book.find('price').text
    print(f'Title: {title}, Author: {author}, Price: {price}')

El resultado de ejecutar el código anterior es:

Title: Introduction to Python, Author: John Doe, Price: 29.99
Title: Data Science with Python, Author: Jane Smith, Price: 39.95

A continuación, crearemos un documento XML con información de libros y luego usaremos el módulo para analizarlo y operar sobre él:

Ejemplo

import xml.etree.ElementTree as ET

# Crear un documento XML
root = ET.Element('bookstore')

# Agregar el primer libro
book1 = ET.SubElement(root, 'book')
title1 = ET.SubElement(book1, 'title')
title1.text = 'Introduction to Python'
author1 = ET.SubElement(book1, 'author')
author1.text = 'John Doe'
price1 = ET.SubElement(book1, 'price')
price1.text = '29.99'

# Agregar el segundo libro
book2 = ET.SubElement(root, 'book')
title2 = ET.SubElement(book2, 'title')
title2.text = 'Data Science with Python'
author2 = ET.SubElement(book2, 'author')
author2.text = 'Jane Smith'
price2 = ET.SubElement(book2, 'price')
price2.text = '39.95'

# Guardar el documento XML en un archivo
tree = ET.ElementTree(root)
tree.write('books.xml')

# Analizar el documento XML desde el archivo
parsed_tree = ET.parse('books.xml')
parsed_root = parsed_tree.getroot()

# Recorrer el árbol XML e imprimir la información de los libros
for book in parsed_root.findall('book'):
    title = book.find('title').text
    author = book.find('author').text
    price = book.find('price').text
    print(f'Title: {title}, Author: {author}, Price: {price}')

En el ejemplo anterior, primero creamos un documento XML que contiene información de dos libros; luego guardamos este documento en el archivo books.xml. A continuación, usamos el método ET.parse() para analizar el documento XML del archivo, recorremos el árbol del documento, extraemos e imprimimos el título, el autor y el precio de cada libro.


Python usa SAX para analizar XML

SAX es una API basada en eventos.

El uso de SAX para analizar documentos XML involucra dos partes:AnalizadoryManejador de eventos。

El analizador se encarga de leer el documento XML y enviar eventos al manejador de eventos, como los eventos de inicio y fin de elemento.

El manejador de eventos es responsable de responder a los eventos y procesar los datos XML transmitidos.

  • 1. Procesar archivos grandes;
  • 2. Solo se necesita parte del contenido del archivo, o solo se necesita obtener información específica del archivo.
  • 3. Cuando se desea construir su propio modelo de objetos.

Para procesar XML con sax en Python, primero debe importar la función parse de xml.sax y ContentHandler de xml.sax.handler.

Introducción a los métodos de la clase ContentHandler

Método characters(content)

Momento de la llamada:

Desde el inicio de la línea, antes de encontrar una etiqueta, si hay caracteres, el valor de content es esas cadenas.

Desde una etiqueta, antes de encontrar la siguiente etiqueta, si hay caracteres, el valor de content es esas cadenas.

Desde una etiqueta, antes de encontrar el fin de línea, si hay caracteres, el valor de content es esas cadenas.

Las etiquetas pueden ser etiquetas de inicio o etiquetas de fin.

Método startDocument()

Se llama cuando se inicia el documento.

Método endDocument()

Se llama cuando el analizador llega al final del documento.

Método startElement(name, attrs)

Se llama al encontrar una etiqueta de inicio XML; name es el nombre de la etiqueta, attrs es un diccionario de los valores de los atributos de la etiqueta.

Método endElement(name)

Se llama al encontrar una etiqueta de fin XML.


Método make_parser

El siguiente método crea un nuevo objeto analizador y lo devuelve.

xml.sax.make_parser( [parser_list] )

Descripción de parámetros:

  • parser_list- Parámetro opcional, lista de analizadores

Método parser

El siguiente método crea un analizador SAX y analiza un documento XML:

xml.sax.parse( xmlfile, contenthandler[, errorhandler])

Descripción de parámetros:

  • xmlfile- Nombre del archivo XML
  • contenthandler- Debe ser un objeto ContentHandler
  • errorhandler- Si se especifica este parámetro, errorhandler debe ser un objeto SAX ErrorHandler

Método parseString

El método parseString crea un analizador XML y analiza la cadena xml:

xml.sax.parseString(xmlstring, contenthandler[, errorhandler])

Descripción de parámetros:

  • xmlstring- Cadena XML
  • contenthandler- Debe ser un objeto ContentHandler
  • errorhandler- Si se especifica este parámetro, errorhandler debe ser un objeto SAX ErrorHandler

Ejemplo de análisis XML en Python

Ejemplo

#!/usr/bin/python3

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 = ""

   # Llamada al inicio del elemento
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag == "movie":
         print ("*****Movie*****")
         title = attributes["title"]
         print ("Title:", title)

   # Llamada al final del elemento
   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 = ""

   # Llamada al leer caracteres
   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__"):
   
   # Crear un XMLReader
   parser = xml.sax.make_parser()
   # Desactivar el espacio de nombres
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)

   # Sobrescribir ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )
   
   parser.parse("movies.xml")

El resultado de ejecutar el código anterior es el siguiente:

*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom

Consulte la documentación completa de la API SAXPython SAX APIs


Usar xml.dom para analizar XML

El Modelo de Objetos del Documento (Document Object Model, abreviado DOM) es una interfaz de programación estándar recomendada por el W3C para procesar lenguajes de marcado extensibles.

Al analizar un documento XML, un analizador DOM lee todo el documento de una sola vez y guarda todos los elementos del documento en una estructura de árbol en memoria; después, puedes utilizar las distintas funciones que proporciona DOM para leer o modificar el contenido y la estructura del documento, y también puedes escribir el contenido modificado en un archivo XML.

En Python se usa xml.dom.minidom para analizar archivos XML, por ejemplo:

Ejemplo

#!/usr/bin/python3

from xml.dom.minidom import parse
import xml.dom.minidom

# Abrir el documento XML con el analizador minidom
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print ("Root element : %s" % collection.getAttribute("shelf"))

# Obtener todas las películas de la colección
movies = collection.getElementsByTagName("movie")

# Imprimir los detalles de cada película
for movie in movies:
   print ("*****Movie*****")
   if movie.hasAttribute("title"):
      print ("Title: %s" % movie.getAttribute("title"))

   type = movie.getElementsByTagName('type')[0]
   print ("Type: %s" % type.childNodes[0].data)
   format = movie.getElementsByTagName('format')[0]
   print ("Format: %s" % format.childNodes[0].data)
   rating = movie.getElementsByTagName('rating')[0]
   print ("Rating: %s" % rating.childNodes[0].data)
   description = movie.getElementsByTagName('description')[0]
   print ("Description: %s" % description.childNodes[0].data)

El resultado de ejecutar el programa anterior es el siguiente:

Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom

Consulte la documentación completa de la API DOMPython DOM APIs。

Otras extensiones