Generar un fichero XML con DOM

written by uve 6 April 2011

Ayer hablaba un poquito en general acerca de distintos tipos de interfazces para parsear documentos XML. Hoy he preparado un par de ejemplos de como generar un documento XML.

Los ejemplos están hechos en Python, el cuál es ideal para mostrar su funcionamiento. Esto se debe a que Python incluye en su librería estándar un módulo xml, por lo que no es necesario instalar nada extra. Además he utilizado el módulo xml.dom.minidom. minidom es una implementación ligera de la interfaz DOM, cuyo objetivo es ser más rápido y ligero.

Los ejemplos están disponibles aquí.

En los ejemplos de hoy, he utilizado el XML que se me ocurrió ayer mientras explicaba algunas interfaces para el parseo:

<mema>
  <noticia>
    <titulo>Generar un fichero XML con DOM</titulo>
    <autor>uve</autor>
  </noticia>
</mema>

Los conceptos que hay que saber para trabajar con DOM a nivel básico, son los siguientes:

  • Elemento: representa una etiqueta, por ejemplo <autor></autor>
  • Elemento raíz: es la etiqueta de más alto nivel, en el ejemplo <mema></mema>
  • Atributo: información adicional de una etiqueta <etiqueta atributo="valor"></atributo>

Veamos esto en un ejemplo:

import datetime
from xml.dom.minidom import Document

timestamp = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')

# Creamos un documento nuevo
doc = Document()
# Creamos la etiqueta raíz <mema> </mema>
mema = doc.createElement('mema')
mema.setAttribute('timestamp', timestamp)
doc.appendChild(mema)

# Añadimos una noticia <noticia> </noticia>
noticia = doc.createElement('noticia')
mema.appendChild(noticia)
# <titulo> </titulo>
titulo = doc.createElement('titulo')
text = doc.createCDATASection('Generar un fichero XML con DOM')
titulo.appendChild(text)
noticia.appendChild(titulo)
# <autor> </autor>
autor = doc.createElement('autor')
text = doc.createCDATASection('uve')
autor.appendChild(text)
noticia.appendChild(autor)

Lo primero que realizamos es crear el documento, y a partir de aquí se realizan el resto de operaciones:

doc = Document()

Cada vez que queremos añadir un elemento, primero lo creamos y después lo añadimos al elemento correspondiente:

mema = doc.createElement('mema')
doc.appendChild(mema)

Además, existen las secciones CDATA. Estas secciones indican al parser que el contenido de la sección no se debe de parsear, es decir, se ignora su contenido. Por ejemplo:

<![CDATA[<p>hola</p>]]>

Con esto, nos aseguramos que el elmento <p> no se tenga en cuenta a la hora de parsear el documento.

Y para terminar un ejemplo un poco más elaborado:

import datetime
from xml.dom.minidom import Document

class Noticia(object):
    def __init__(self, titulo, autor):
        self.titulo = titulo
        self.autor = autor

# Generamos un listado de noticias
lista_noticias = []

noticia = Noticia('Interfaces de programación de documentos XML', 'uve')
lista_noticias.append(noticia)
noticia = Noticia('Generar un fichero XML con DOM', 'uve')
lista_noticias.append(noticia)

# Preparamos una marca de tiempo para añadirsela al documento
timestamp = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')

# Creamos un documento nuevo
doc = Document()
# Creamos la etiqueta raíz <mema> </mema>
mema = doc.createElement('mema')
mema.setAttribute('timestamp', timestamp)
doc.appendChild(mema)
# Añadimos la lista de noticias al documento
for n in lista_noticias:
    # <noticia> </noticia>
    noticia = doc.createElement('noticia')
    mema.appendChild(noticia)
    # <titulo> </titulo>
    titulo = doc.createElement('titulo')
    text = doc.createCDATASection(n.titulo)
    titulo.appendChild(text)
    noticia.appendChild(titulo)
    # <autor> </autor>
    autor = doc.createElement('autor')
    text = doc.createCDATASection(n.autor)
    autor.appendChild(text)
    noticia.appendChild(autor)

Tags

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.