Su primera tarea es elegir un formato de parche. El formato más difícil para los humanos para leer (en mi humilde opinión) resulta ser el formato más fácil de aplicar para el software: el script ed (1). Puede comenzar con un simple /usr/bin/diff -e old.xml new.xml
para generar los parches; diff (1) producirá parches orientados a la línea, pero debería estar bien para empezar. El formato ed ve así:
36a
<tr><td class="eg" style="background: #182349;"> </td><td><tt>#182349</tt></td></tr>
.
34c
<tr><td class="eg" style="background: #66ccff;"> </td><td><tt>#xxxxxx</tt></td></tr>
.
20,23d
Los números son números de línea, los intervalos de número de línea son separados por comas. A continuación hay tres comandos individuales de letras:
- un: añadir el siguiente bloque de texto en esa posición.
- c: cambie el texto en esta posición al siguiente bloque. Esto es equivalente a d seguido de un un comando.
- d: elimine estas líneas.
También notará que los números de línea en el parche van de abajo hacia arriba para que no tenga que preocuparse por los cambios que ensucian los números de las líneas en trozos posteriores del parche. Los fragmentos reales de texto que se agregarán o cambiarán seguirán los comandos como una secuencia de líneas terminadas por una línea con un único período (es decir, /^\.$/
o patch_line == '.'
según su preferencia). En resumen, el formato es el siguiente:
[line-number-range][command]
[optional-argument-lines...]
[dot-terminator-if-there-are-arguments]
Por lo tanto, la aplicación de un ed parche, todo lo que necesita hacer es cargar el archivo de destino en una matriz (un elemento por línea), analizar el parche usando una máquina de estado simple, llame al Array#insert para agregar nuevas líneas y Array#delete_at para eliminarlas. No debe tomar más de un par de docenas de líneas de Ruby para escribir el parche y no se necesita ninguna biblioteca.
Si usted puede arreglar su XML para salir de esta manera:
<tag>
blah blah
</tag>
<other-tag x="y">
mumble mumble
</other>
en lugar de:
<tag>blah blah</tag><other-tag x="y">mumble mumble</other>
entonces el enfoque orientado a simple línea anterior funcionará bien; los EOL extra no van a costar mucho espacio así que ve por una implementación fácil para comenzar.
Hay bibliotecas de Ruby para producir diffs entre dos matrices (google "ruby algorithm :: diff" para comenzar). La combinación de una biblioteca de diferencias con un analizador XML le permitirá producir parches basados en etiquetas en lugar de en línea, y esto podría ser más conveniente. Lo importante es la elección de los formatos de parche, una vez que elija el formato ed (y se dé cuenta de la sabiduría del parche que funciona de abajo hacia arriba), entonces todo lo demás encajará prácticamente con el mínimo esfuerzo.
Tengo control total sobre el formato de archivo de parche. El servidor ejecuta Java/Linux, por lo que debe haber muchas opciones estándar, y también puedo ajustar el formato a cualquier cosa que sea útil. –