Ihre erste Aufgabe besteht darin, ein Patch-Format zu wählen. Das schwerste Format für Menschen zu lesen (meiner bescheidenen Meinung nach) stellt sich als das einfachste Format heraus, das Software anwenden kann: das ed(1) Skript. Sie können mit einem einfachen /usr/bin/diff -e old.xml new.xml
beginnen, um die Patches zu generieren; diff(1) wird zeilenorientierte Patches erzeugen, aber das sollte zum Einstieg in Ordnung sein. Das ed-Format sieht so aus:
36a
#182349
.
34c
#xxxxxx
.
20,23d
Die Zahlen sind Zeilennummern, Zeilennummernbereiche sind durch Kommas getrennt. Dann gibt es drei einzelne Buchstaben-Befehle:
- a: fügen Sie den nächsten Textblock an dieser Position hinzu.
- c: ändern Sie den Text an dieser Position in den folgenden Block. Dies entspricht einem d gefolgt von einem a Befehl.
- d: löschen Sie diese Zeilen.
Sie werden auch bemerken, dass die Zeilennummern im Patch von unten nach oben gehen, so dass Sie sich keine Sorgen darüber machen müssen, dass Änderungen die Zeilennummern in nachfolgenden Teilen des Patches durcheinanderbringen. Die tatsächlichen Textblöcke, die hinzugefügt oder geändert werden sollen, folgen den Befehlen als Sequenz von Zeilen, die durch eine Zeile mit einem einzelnen Punkt abgeschlossen sind (d.h. /^\.$/
oder patch_line == '.'
je nach Präferenz). Zusammengefasst sieht das Format so aus:
[Zeilennummernbereich][Befehl]
[optionale Argumentzeilen...]
[Punkt-Terminator, wenn Argumente vorhanden sind]
Um einen ed Patch anzuwenden, laden Sie einfach die Zieldatei in ein Array (ein Element pro Zeile), analysieren den Patch mit einer einfachen Zustandsmaschine, rufen Array#insert auf, um neue Zeilen hinzuzufügen, und Array#delete_at, um sie zu entfernen. Es sollte nicht mehr als ein paar Dutzend Zeilen Ruby benötigen, um den Patcher zu schreiben, und es ist keine Bibliothek erforderlich.
Wenn Sie Ihr XML so anordnen können, dass es so aussieht:
bla bla
murmeln murmeln
anstatt:
bla blamurmeln murmeln
dann wird der oben beschriebene einfache zeilenorientierte Ansatz gut funktionieren; die zusätzlichen Zeilenumbrüche werden nicht viel Platz kosten, also wählen Sie zur einfachen Implementierung den einfacheren Weg zum Starten.
Es gibt Ruby-Bibliotheken zum Erzeugen von Diffs zwischen zwei Arrays (googlen Sie "ruby algorithm::diff" um zu beginnen). Durch die Kombination einer Diff-Bibliothek mit einem XML-Parser können Sie Patches erstellen, die auf Tags basieren, anstatt auf Zeilen, und das könnte besser zu Ihnen passen. Das Wichtige ist die Wahl des Patch-Formats, sobald Sie das ed Format gewählt haben (und die Weisheit des Patches, der von unten nach oben funktioniert, erkannt haben), fällt so ziemlich alles andere mit wenig Aufwand an seinen Platz.
0 Stimmen
Ich habe die volle Kontrolle über das Patch-Dateiformat. Der Server läuft auf Java/Linux, also sollte es viele Standardoptionen geben, und ich kann auch das Format anpassen, um alles zu machen, was hilfreich wäre.