Python 3 - Procesamiento XML

XML es un lenguaje portátil de código abierto que permite a los programadores desarrollar aplicaciones que pueden ser leídas por otras aplicaciones, independientemente del sistema operativo y / o lenguaje de desarrollo.

¿Qué es XML?

El lenguaje de marcado extensible (XML) es un lenguaje de marcado muy parecido al HTML o SGML. Esto es recomendado por el Consorcio World Wide Web y está disponible como estándar abierto.

XML es extremadamente útil para realizar un seguimiento de pequeñas y medianas cantidades de datos sin necesidad de una red troncal basada en SQL.

Arquitecturas y API de XML Parser

La biblioteca estándar de Python proporciona un conjunto mínimo pero útil de interfaces para trabajar con XML.

Las dos API para datos XML más básicas y más utilizadas son las interfaces SAX y DOM.

  • Simple API for XML (SAX)- Aquí, registra devoluciones de llamada para eventos de interés y luego deja que el analizador continúe con el documento. Esto es útil cuando sus documentos son grandes o tiene limitaciones de memoria, analiza el archivo a medida que lo lee desde el disco y el archivo completo nunca se almacena en la memoria.

  • Document Object Model (DOM) API - Ésta es una recomendación del World Wide Web Consortium en la que todo el archivo se lee en la memoria y se almacena en forma jerárquica (basada en árboles) para representar todas las características de un documento XML.

SAX obviamente no puede procesar información tan rápido como DOM, cuando trabaja con archivos grandes. Por otro lado, el uso exclusivo de DOM puede acabar con sus recursos, especialmente si se utiliza en muchos archivos pequeños.

SAX es de solo lectura, mientras que DOM permite cambios en el archivo XML. Dado que estas dos API diferentes se complementan literalmente entre sí, no hay ninguna razón por la que no pueda usarlas para proyectos grandes.

Para todos nuestros ejemplos de código XML, usemos un archivo XML simple movies.xml como entrada:

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

Analizar XML con API SAX

SAX es una interfaz estándar para el análisis de XML controlado por eventos. Analizar XML con SAX generalmente requiere que cree su propio ContentHandler subclasificando xml.sax.ContentHandler.

Su ContentHandler maneja las etiquetas y atributos particulares de su (s) sabor (s) de XML. Un objeto ContentHandler proporciona métodos para manejar varios eventos de análisis. Su analizador propietario llama a los métodos ContentHandler mientras analiza el archivo XML.

Los métodos startDocument y endDocument se llaman al principio y al final del archivo XML. Los caracteres del método (texto) pasan los datos de caracteres del archivo XML a través del texto del parámetro.

El ContentHandler se llama al principio y al final de cada elemento. Si el analizador no está en modo de espacio de nombres, los métodos startElement (etiqueta, atributos) y endElement (etiqueta) se llaman; de lo contrario, se llaman a los métodos correspondientes startElementNS y endElementNS . Aquí, etiqueta es la etiqueta del elemento y atributos es un objeto de atributos.

Aquí hay otros métodos importantes que debe comprender antes de continuar:

El método make_parser

El siguiente método crea un nuevo objeto analizador y lo devuelve. El objeto de analizador creado será del primer tipo de analizador, según el sistema.

xml.sax.make_parser( [parser_list] )

Aquí están los detalles de los parámetros:

  • parser_list - El argumento opcional que consiste en una lista de analizadores a utilizar que deben implementar el método make_parser.

El método de análisis

El siguiente método crea un analizador SAX y lo usa para analizar un documento.

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

Aquí están los detalles de los parámetros:

  • xmlfile - Este es el nombre del archivo XML para leer.

  • contenthandler - Debe ser un objeto ContentHandler.

  • errorhandler - Si se especifica, errorhandler debe ser un objeto SAX ErrorHandler.

El método parseString

Hay un método más para crear un analizador SAX y analizar el especificado XML string.

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

Aquí están los detalles de los parámetros:

  • xmlstring - Este es el nombre de la cadena XML para leer.

  • contenthandler - Debe ser un objeto ContentHandler.

  • errorhandler - Si se especifica, errorhandler debe ser un objeto SAX ErrorHandler.

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

   # Call when an element starts
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag == "movie":
         print ("*****Movie*****")
         title = attributes["title"]
         print ("Title:", title)

   # Call when an elements ends
   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 = ""

   # Call when a character is read
   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__"):
   
   # create an XMLReader
   parser = xml.sax.make_parser()
   # turn off namepsaces
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)

   # override the default ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )
   
   parser.parse("movies.xml")

Salida

Esto produciría el siguiente resultado:

*****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 scientific 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

Para obtener detalles completos sobre la documentación de la API SAX, consulte las API estándar de Python SAX .

Analizar XML con DOM API

El Document Object Model ("DOM") es una API en varios idiomas del Consorcio World Wide Web (W3C) para acceder y modificar los documentos XML.

El DOM es extremadamente útil para aplicaciones de acceso aleatorio. SAX solo le permite ver un fragmento del documento a la vez. Si está mirando un elemento SAX, no tiene acceso a otro.

Esta es la forma más fácil de cargar un documento XML rápidamente y crear un objeto minidom usando el módulo xml.dom. El objeto minidom proporciona un método de analizador simple que crea rápidamente un árbol DOM a partir del archivo XML.

La frase de muestra llama a la función parse (file [, parser]) del objeto minidom para analizar el archivo XML, designado por file en un objeto de árbol DOM.

Ejemplo

#!/usr/bin/python3

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

# Open XML document using minidom parser
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print ("Root element : %s" % collection.getAttribute("shelf"))

# Get all the movies in the collection
movies = collection.getElementsByTagName("movie")

# Print detail of each movie.
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)

Salida

Esto produciría el siguiente resultado:

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

Para obtener detalles completos sobre la documentación de la API DOM, consulte las API DOM estándar de Python .