Porównanie dokumentów

Porównanie dokumentów

Porównanie dokumentów

Ten przewodnik pokazuje, jak porównać dwa ciągi tekstu i wygenerować sekwencję edycji między nimi przy użyciu silnika tekstowego diff Aspose.PDF FOSS dla .NET. Punktem wejścia dla tego modelu porównania jest DiffOperation, pojedyncza edycja oznaczona Operation (Equal, Delete, lub Insert), wraz z DiffUtils klasą pomocniczą służącą do znajdowania wspólnego tekstu oraz składania diffu z powrotem do tekstu źródłowego i docelowego. Oddzielny etap optymalizacji, opisany w Optymalizacji Diff, kanonizuje surowy wynik diff wygenerowany w ten sposób przed jego renderowaniem lub zastosowaniem.


Model diffu: Operacja i DiffOperation

Operation jest wyliczeniem, które klasyfikuje każdą edycję w diffie: Equal oznacza ciąg tekstu, który jest niezmieniony, Delete oznacza ciąg usunięty ze źródła, a Insert oznacza ciąg dodany w docelowym. DiffOperation łączy wartość Operation z Text, do którego się odnosi, i implementuje IEquatable<DiffOperation>, aby dwie edycje mogły być porównywane pod kątem równości.

using Aspose.Pdf.Comparison.Diff;

// A single edit consists of an Operation and the run of text it applies to.
var unchanged = new DiffOperation(Operation.Equal, "Aspose.PDF ");
var removed = new DiffOperation(Operation.Delete, "for .NET Framework");
var added = new DiffOperation(Operation.Insert, "FOSS for .NET");

Console.WriteLine(unchanged.Operation); // Equal
Console.WriteLine(added.Text);          // "FOSS for .NET"

Wyszukiwanie wspólnego tekstu przy użyciu DiffUtils

DiffUtils jest statyczną klasą pomocniczą używaną przez silnik diff do znajdowania wspólnego prefiksu i sufiksu współdzielonych przez dwa ciągi znaków przed difowaniem różniącej się środkowej części. FindCommonStartParts znajduje wspólny prefiks, a FindCommonEndParts znajduje wspólny sufiks; przeciążenie FindCommonEndParts przyjmuje startIndex, aby wyszukiwanie sufiksu mogło być ograniczone do tekstu następującego po już zlokalizowanym prefiksie.

string original = "The quick brown fox";
string revised = "The quick red fox jumps";

var commonStart = DiffUtils.FindCommonStartParts(original, revised);
var commonEnd = DiffUtils.FindCommonEndParts(original, revised);

Ponowne składanie tekstu z diffu

Gdy różnica jest wyrażona jako ciąg wartości DiffOperation, DiffUtils może odtworzyć obie strony porównania: AssemblySourceText odtwarza oryginalny tekst z uruchomień Equal i Delete, a AssemblyDestinationText odtwarza zmieniony tekst z uruchomień Equal i Insert.

using System.Collections.Generic;

var diffs = new List<DiffOperation>
{
    new DiffOperation(Operation.Equal, "The quick "),
    new DiffOperation(Operation.Delete, "brown"),
    new DiffOperation(Operation.Insert, "red"),
    new DiffOperation(Operation.Equal, " fox")
};

string sourceText = DiffUtils.AssemblySourceText(diffs);
string destinationText = DiffUtils.AssemblyDestinationText(diffs);

Console.WriteLine(sourceText);      // "The quick brown fox"
Console.WriteLine(destinationText); // "The quick red fox"

Porównywanie i raportowanie edycji

DiffOperation nadpisuje Equals, GetHashCode i ToString, dzięki czemu edycje można porównywać pod kątem równości lub zapisywać do logów i wyników testów bez dodatkowego kodu konwersji.

var a = new DiffOperation(Operation.Equal, "PDF");
var b = new DiffOperation(Operation.Equal, "PDF");

bool same = a.Equals(b); // true - same Operation and Text
Console.WriteLine(a.ToString());

Wskazówki i najlepsze praktyki

  • DiffOperation jest niezmienny i implementuje IEquatable<DiffOperation> — użyj Equals, aby porównać dwie edycje zamiast sprawdzać równość referencji.
  • Najpierw znajdź wspólny prefiks przy użyciu FindCommonStartParts, a następnie przekaż jego długość do przeciążenia startIndex w FindCommonEndParts, aby uniknąć podwójnego liczenia krótkiego wspólnego prefiksu jako części sufiksu.
  • Użyj AssemblySourceText i AssemblyDestinationText, aby zweryfikować, że ciąg wartości DiffOperation przechodzi w obie strony do dokładnego oryginalnego i zmienionego tekstu, zanim użyjesz go w innym miejscu.
  • Traktuj uruchomienia Operation.Equal jako operacje bez efektu przy renderowaniu wizualnej różnicy i podświetlaj tylko uruchomienia Delete i Insert.
  • Ten silnik porównuje tekst, a nie dokumenty bezpośrednio — wyodrębnij tekst, który chcesz porównać (na przykład z strony lub dokumentu) przed utworzeniem różnicy.

Typowe problemy

ProblemPrzyczynaNapraw
AssemblySourceText / AssemblyDestinationText wynik nie pasuje do oryginałówLista diffs jest niekompletna lub jej pozycje DiffOperation są w nieprawidłowej kolejnościDołącz wszystkie edycje w kolejności, w której pierwotnie wystąpiły
FindCommonEndParts zwraca nieoczekiwany wynik dla krótkich, podobnych ciągówWyszukiwanie wspólnego przyrostka zachodzi na tekst już dopasowany przez FindCommonStartPartsPrzekaż długość zwróconą przez FindCommonStartParts jako argument startIndex
Equals zwraca false dla edycji, które wyglądają identycznieWartości Text różnią się spacjami lub wielkością literZnormalizuj tekst (przytnij / zignoruj wielkość liter) przed tworzeniem wartości DiffOperation, które zamierzasz porównać
Wynik diff jest hałaśliwy lub niepotrzebnie fragmentarycznySurowe ciągi DiffOperation nie są jeszcze kanonikalizowanePrzeprowadź ciąg przez etap optymalizacji opisany w Optymalizacja Diff

FAQ

Co porównuje silnik Diff?

Porównuje fragmenty tekstu i generuje ciąg wartości DiffOperation opisujących edycje — niezmieniony, usunięty lub wstawiony tekst — potrzebne do przekształcenia jednego łańcucha w drugi.

Jakie typy edycji obsługuje Operation?

Trzy: Equal dla niezmienionego tekstu, Delete dla tekstu usuniętego ze źródła oraz Insert dla tekstu dodanego w miejscu docelowym.

Jak sprawdzić, czy dwie edycje są takie same?

Wywołaj Equals na instancji DiffOperation, lub porównaj bezpośrednio jej właściwości Operation i Text.

Czy mogę odzyskać oryginalny i zmodyfikowany tekst z diffu?

Tak — przekaż listę wartości DiffOperation do DiffUtils.AssemblySourceText dla tekstu oryginalnego oraz DiffUtils.AssemblyDestinationText dla tekstu zmienionego.

Czy ta strona obejmuje scalanie lub czyszczenie diffu?

Nie — kanonikalizacja surowego diffu (scalanie sąsiadujących fragmentów, przesuwanie edycji przez równości) jest opisane osobno w Optymalizacja diffu.


API Reference Podsumowanie

Klasa / MetodaOpis
OperationEnum klasyfikujące edycję jako Equal, Delete lub Insert
DiffOperationPojedyncza edycja: Operation połączony z Text, do którego ma zastosowanie
DiffOperation.OperationWartość Operation dla tej edycji
DiffOperation.TextFragment tekstu, którego dotyczy ta edycja
DiffOperation.EqualsPorównuje dwie edycje pod kątem równości według Operation i Text
DiffOperation.ToStringRenderuje edycję jako ciąg znaków do logowania lub wyświetlania
DiffUtilsStatyczna klasa pomocnicza z narzędziami do różnicowania tekstu
DiffUtils.FindCommonStartPartsZnajduje wspólny prefiks dwóch ciągów znaków
DiffUtils.FindCommonEndPartsZnajduje wspólny sufiks dwóch ciągów znaków, opcjonalnie zaczynając od indeksu
DiffUtils.AssemblySourceTextSkłada ponownie oryginalny tekst z listy wartości DiffOperation
DiffUtils.AssemblyDestinationTextSkłada ponownie zrewidowany tekst z listy wartości DiffOperation

Zobacz także

 Polski