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><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>
¿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:
- Lee el nombre del fichero de la entrada standard
- Comprueba que el fichero existe y que el mismo se puede leer
- Almacena el contenido del fichero en una variable
- Decodifica entidades html
- Formatea el XML
- 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):
- Ejecutamos gedit
- Menu > Tools > Manage External Tool
- Agregamos una nueva herramienta externa y establecemos los valores como muestra la figura
Abrimos nuestro fichero xml al cual le llamamos 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.
Excelente post, estoy usando el script en python con unas pequeñas modificaciones para hacerlo funcionar como acción personalizada en thunar, además de un port a python3.
El repo github donde lo tengo alojado es en:
https://github.com/danesc87/dotsAndConfs
Gracias por tu contribución y hace un port a python3, los scripts anteriores también se pueden encontrar en:
Python: https://gist.github.com/yoander/ae488ac7465a9e77f6f63b0c61e58f5c
PHP: https://gist.github.com/yoander/7b9821ad5d077dc88cc29e1ab031ea0f
Ambos script pueden usarse, distribuirse y modificarse libremente ya que son liberados bajos licencia GPLv2+