heinetz: Diff für HTML

Hallo Forum,

seit 4 Wochen versuche ich nun immernoch eine einfach Änderungsverfolgung
für html umzusetzen und kriegs nicht hin. Dabei kann das eigentlich nicht
so schwer sein. Ich habe zwei HTML-Strings als PHP-Variablen und will einen
Outpu erzeugen, der die beiden HTML-Strings 'merged' und die Unterschiede
kenntlich macht.

$str_1 = "<p>Hello World</p>";  
$str_2 = "<p>Hola World</p>";  
  
echo display_diff($str_1, $str_2);  
  
Ausgabe:  
<p><span class="del">Hello</span><span class="ins">Hola</span> World</p>

Nun gibt es ja einige Lösungen, die den Diff-Algorithmus als PHP umsetzen,
einige Ansätze, das als HTML auszugeben, wie ich es mir vorstelle. Ich habe
PEAR:text_diff ausprobiert, versucht das in MediaWiki verwendete DaisyDiff
zu verwenden und letztendlich die recht einfache Lösung PHP SimpleDiff gefunden.
Alle arbeiten im Grunde gleichermassen, indem sie zwei Arrays vergleichen
und die Unterschiede kenntlich machen. Nachdem ich mich nun lange mit dem
Thema befasst habe, komme ich zu dem Schluss, dass das einzige Problem die
Arrays selbst zu sein scheinen. Wie mache ich aus der HTML-Struktur
eindimensionale Arrays, die dann verglichen werden?

Der DIFF-Algorithmus in seiner ursprünglichen Form zerlegt einen String
nach Umbrüchen, PHP SimpleDiff zerlegt die Strings durch explode(' ', $str). nach Leerzeichen. Das alles taugt nicht wirklich, um HTML-Strukturen zu vergleichen. Ich glaube, die Frage ist, wie kriege ich die
HTML-Struktur in ein eindimensionales Array.

puhh, hat sich jemand schonmal mit der Aufgabe befasst?

beste gruesse,
heinetz

  1. Moin!

    puhh, hat sich jemand schonmal mit der Aufgabe befasst?

    Das Problem ist nicht ohne weiteres lösbar, weil der wirklich sinnvolle Trenner nicht ohne weiteres bestimmbar ist, die ergibt sich ja aus der Aufgabe- Vielleicht willst Du in einem Formular mehrerer Möglichkeiten anbieten.

    Eine weitere denkbare und durchaus Sinn machende Variante wäre jedes ">" durch ">\n" und jedes "<" durch "\n<" zu ersetzen und dann den Array durch splitten nach "\n" zu erzeugen.

    Aus
    ---

      
    <H1>Tolle Überschrift</h1><p>Das ist ein toller Absatz</p>  
    
    

    ----
    wird dann:

    ---

      
    <h1>  
    Tolle Überschrift  
    </h1>  
    <p>  
    Das ist ein toller Absatz.  
    </p>  
    
    

    ---

    Möglicherweise willst Du vorher noch aufeinanderfolgende Zeilenumbrüche reduzieren.

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix

    1. hi,

      danke erstmal für den Tipp!

      Eine weitere denkbare und durchaus Sinn machende Variante wäre jedes ">" durch ">\n" und jedes "<" durch "\n<" zu ersetzen und dann den Array durch splitten nach "\n" zu erzeugen.

      Die Idee ist nicht schlecht. Damit würde dann aus:

      <h1>  
      Tolle Überschrift  
      </h1>  
      <p>  
      Das ist ein toller Absatz.  
      </p>
      
      array(  
      '<h1>',  
      'Tolle Überschrift',  
      '</h1>',  
      '<p>',  
      'Das ist ein toller Absatz.'  
      '</p>');
      

      oder weiter gedacht:

      array(  
      '<h1>',  
      'Tolle',  
      'Überschrift',  
      '</h1>',  
      '<p>',  
      'Das',  
      'ist',  
      'ein'  
      'toller'  
      'Absatz.'  
      '</p>');
      

      Ich werde das wohl erstmal ausprobieren müssen ...

      beste gruesse,
      heinetz