2009-09-01 3 views
8

Necesito tomar dos bloques de texto con etiquetas html y hacer una comparación: combine los dos bloques de texto y luego resalte lo que se agregó o eliminó de una versión a la siguiente.Cómo mostrar una comparación de bloques de texto de 2 html

He utilizado la clase PEAR Text_Diff para realizar comparaciones con éxito de texto plain, pero cuando trato de arrojar texto con etiquetas html, se pone feo. Debido a la palabra y los algoritmos de comparación basados ​​en caracteres que usa la clase, las etiquetas html se rompen y termino con cosas feas como <p><span class="new"> </</span>p>. Mata el html.

¿Hay alguna forma de generar una comparación de texto conservando el marcado html válido original?

Gracias por la ayuda. He estado trabajando en esto durante semanas: [

Esta es la mejor solución que se me ocurrió: encontrar/reemplazar cada tipo de etiqueta html con 1 carácter especial no estándar como el logotipo de manzana (optar shift k), renderice la comparación con este tipo de rebajas primativas, luego invierta los caracteres no estándar de nuevo en etiquetas. ¿Cualquier retroalimentación?

Respuesta

1

El problema parece ser que su programa de diferenciación debe ser el tratamiento de etiquetas HTML existentes como tokens atómicas y no como individuo caracteres.

Si su motor tiene la capacidad de limitarse a trabajar en límites de palabras, vea si puede anular la función que determina los límites de las palabras para que reconozca y trate las etiquetas HTML como una sola "palabra".

También podría hacer lo que dice y crear un diccionario de búsqueda de etiquetas HTML distintas que sustituyan a cada una con un valor Unicode diferente no utilizado (creo que hay algunos rangos definidos por el usuario que puede usar). Sin embargo, si hace esto, cualquier cambio en el marcado será tratado como si fuera un cambio a la palabra anterior o siguiente, porque el carácter Unicode se convertirá en parte de esa palabra para el tokenizador. Agregar un espacio antes y después de cada uno de los caracteres Unicode de token mantendría los cambios de la etiqueta HTML por separado de los cambios de texto sin formato.

+0

El token encontrar/reemplazar unicode es lo que finalmente funcionó. Acabo de hacer una matriz de clave => valor con cada etiqueta de apertura y cierre y su carácter unicode asociado. Luego generé la comparación e invertí el token/tag swap. –

+1

También encontré que la secuencia de comandos Simple Dif de Paul Butler funciona mucho mejor para texto largo que el paquete PEAR. PEAR se centró palabra por palabra, mientras que la configuración de Butcher produjo una mejor salida con las diferencias restantes fragmentadas juntas como cadenas. Enlace: http://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php –

+0

Hola @SteveG., ¿Qué tipo de Unicodes usaste? Porque si se trata con "\\ u123" o "% 3C" para "<", algunos algoritmos de diferencias no se consideran como la misma palabra. Y si hago un mapa usando las teclas solo con números como letras, ¿cómo puedo garantizar que no entren en conflicto con otra cosa en la parte de texto de html? ¡Gracias! http://i.imgur.com/OAJUAP1.png – Luccas

0

intente ejecutar los bloques de HTML a través de esta primera función:

htmlentities(); 

Eso se debe convertir toda su "<" 's y '>'' s en sus códigos correspondientes, tal vez arreglar su problema.

//Example: 
$html_1 = "<html><head></head><body>Something</body></html>" 
$html_2 = "<html><head></head><body><p id='abc'>Something Else</p></body></html>" 

//Below code taken from http://www.go4expert.com/forums/showthread.php?t=4189. 
//Not sure if/how it works exactly 

$diff = &new Text_Diff(htmlentities($html_1), htmlentities($html_2)); 
$renderer = &new Text_Diff_Renderer(); 
echo $renderer->render($diff); 
+0

Gracias por la respuesta rápida ... pero eso realmente empeoraría el problema:/porque entonces las etiquetas se convertirían en cadenas multi-char incluso más largas, que la clase de comparación se romperá. El resultado final debe ser un marcado HTML válido para que se pueda mostrar en una página web. No quiero que el usuario final vea ninguna etiqueta html; necesita ver el html renderizado en una página. El texto que estoy tratando se puede considerar como artículos de blog, solo etiquetas h, p, a e img. Solo quiero agregar resaltado para mostrar qué cambió. –

3

simple de diferencias, por Paul Butler, parece que está diseñado para hacer exactamente lo que necesita: http://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php

Aviso en su código PHP que hay un contenedor de HTML: HTMLDiff ($ edad, $ nueva)

(su entrada en el blog sobre el mismo: http://paulbutler.org/archives/a-simple-diff-algorithm-in-php/

+0

Este algoritmo funciona mucho mejor que el PEAR. Gracias por señalar el recurso. –

+0

Genial. Eres bienvenido. – micahwittman

1

¿Qué pasa con el uso de un tidier/formateador html en cada bloque primero? Esto creará una "estructura" estándar que su diff podría encontrar más fácil de tragar

0

Una copia de mi propia respuesta de here.


¿Qué hay de DaisyDiff (Java y PHP vesions disponibles).

Las siguientes características son muy agradables:

  • Funciona con HTML mal formado que se pueden encontrar "en la naturaleza".
  • La diferenciación es más especializada en HTML que el árbol XML. Cambiar parte de un nodo de texto no hará que se cambie todo el nodo.
  • Además de la diferencia visual predeterminada, la fuente HTML se puede diferir coherentemente.
  • Proporciona descripciones fáciles de entender de los cambios.
  • La GUI predeterminada permite una fácil exploración de las modificaciones a través de atajos de teclado y enlaces.
1

Me pregunto que nadie mencionó HTMLDiff basado en MediaWiki Visual Diff. Pruébalo, estaba buscando algo como tú y lo encontré bastante útil.

+0

Estamos usando esto, pero a veces devuelve un párrafo vacío (cuando no hay diferencias, se supone que devuelve el original sin cambios, pero en este caso hay * * differences) y otras veces mueve HTML (un párrafo eliminado se fusiona con el párrafo anterior al marcar que se eliminó). Solo necesita un poco de amor. –

+0

Y luego está este error ([HTMLDiff está terriblemente roto] (https://phabricator.wikimedia.org/T21859)) que se resolvió al eliminar HTMLDiff de MediaWiki. :( –

+0

@DavidHarkness parte de la razón es que los desarrolladores de MediaWiki no saben que nadie estaba o está usándolo. Los comentarios en phabricator.wikimedia.org serían muy útiles. – Nemo

Cuestiones relacionadas