Formatear XML usando Python o PHP

Para formatear ficheros XML generalmente uso la variante 3 descrita en Formatear ficheros XML pero recientemente he tenido la necesidad de trabajar con ficheros XML que además de estar ofuscado una parte del XML usa entidades html, partamos de que debemos trabajar con un fichero XML como el siguiente:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE Edit_Mensaje SYSTEM "Edit_Mensaje.dtd">
<Edit_Mensaje>
     <Mensaje>
          <Remitente>
               <Nombre>Nombre del remitente</Nombre>
               <Mail> Correo del remitente </Mail>
          </Remitente>
          <Destinatario>
               <Nombre>Nombre del destinatario</Nombre>
               <Mail>Correo del destinatario</Mail>
          </Destinatario>
          <Texto>
               <Asunto>
                    Este es mi documento con una estructura muy sencilla
                    no contiene atributos ni entidades...
               </Asunto>
               <Parrafo>
                    Este es mi documento con una estructura muy sencilla
                    no contiene atributos ni entidades...
               </Parrafo>
          </Texto>
     </Mensaje>
</Edit_Mensaje>

Nota: Fichero Obtenido de Wikipedia: Extensible Markup Language

pero que en lugar de tenerlo como se muestra más arriba lo tenemos de la siguiente manera:

<Edit_Mensaje><Mensaje>&lt;Remitente&gt;&lt;Nombre&gt;Nombre del remitente&lt;/Nombre&gt;&lt;Mail&gt;Correo del remitente&lt;/Mail&gt;&lt;/Remitente&gt;&lt;Destinatario&gt;&lt;Nombre&gt;Nombre del destinatario&lt;/Nombre&gt;&lt;Mail&gt;Correo del destinatario&lt;/Mail&gt;&lt;/Destinatario&gt;&lt;Texto&gt;&lt;Asunto&gt;Este es mi documento con una estructura muy sencilla no contiene atributos ni entidades...&lt;/Asunto&gt;&lt;Parrafo&gt;Este es mi documento con una estructura muy sencilla no contiene atributos ni entidades... &lt;/Parrafo&gt;&lt;/Texto&gt;</Mensaje></Edit_Mensaje>

¿No muy bonito verdad? y no podemos aplicar las soluciones ofrecidas en Formatear ficheros XML debido a que el XML contiene entidades html así que tuve echarle mano y hacer un script primero en Python y luego en PHP:

Scripts

Ambos script ejecutan la siguiente lógica:

  1. Lee el nombre del fichero de la entrada standard
  2. Comprueba que el fichero existe y que el mismo se puede leer
  3. Almacena el contenido del fichero en una variable
  4. Decodifica entidades html
  5. Formatea el XML
  6. Visualiza el XML en un formato entendible

Script en Python

#!/usr/bin/env python3

from argparse import ArgumentParser
from pathlib import Path
from xml.dom.minidom import parseString
import html

parser = ArgumentParser(description = 'Format an XML file')
parser.add_argument('-f', '--file', type = Path, dest = 'file', required = True, help = 'File to format/pretty print')
args = parser.parse_args()

file = args.file

if not file.is_file():
    print(f"File {file} does not exist or is not readable!")
    exit(1)

content = file.read_text()
if not content:
    print(f"File {file} is empty nothing to do!")
    exit(2)

xml = parseString(html.unescape(content))
print(xml.toprettyxml())

Script en PHP

#!/usr/bin/env php

<?php

if (empty($argv[1])) {
    echo "El fichero a formatear es obligatorio\n";
    exit(1);
}

$file_path = $argv[1];

if (!is_readable($file_path)) {
    echo "El fichero $file_path no existe o no se puede leer\n";
    exit(2);
}

if (empty($content = file_get_contents($file_path))) {
    echo "El contenido del fichero $file_path es vacío\n";
    exit(3);
} 

$xml = new DOMDocument();

$xml->loadXML(html_entity_decode($content));
$xml->preserveWhiteSpace= false;
$xml->formatOutput = true;

$xml_formatted = $xml->saveXML();

echo $xml->saveXML();

//file_put_contents('formatted.xml', $xml_formatted);

exit(0);

Ahora podemos integrar los scripts anteriores con gedit para ello (En este caso solo lo haremos para el script desarrollado en PHP):

  1. Ejecutamos gedit
  2. Menu > Tools > Manage External Tool
  3. Agregamos una nueva herramienta externa y establecemos los valores como muestra la figura

gedit-external-tool

Abrimos nuestro fichero xml al cual le llamamos garbage.xml

garbage-xml

Luego lo formateamos usando la combinación de teclas que establecimos cuando integramos la herramientas externa en el gedit y nos quedaría como muestra la figura.

ppxml

Lecturas recomendadas

* Formatear ficheros XML


YouTube video

YouTube video

2 comentarios en “Formatear XML usando Python o PHP”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.