Сравняване

Сравняването на документите е процес, който идентифицира промените между два документа и съдържа промените като ревизии. Този процес сравнява всеки два документа, включително версии на един конкретен документ, след което промените между двата документа ще бъдат показани като ревизии в първия документ.

Методът за сравнение се постига чрез сравняване на думи на ниво характер или на ниво дума. Ако една дума съдържа промяна на поне един символ, в резултат, разликата ще бъде показана като промяна на цялата дума, а не като символ. Този процес на сравнение е обичайна задача в правната и финансовата промишленост.

Вместо ръчно търсене на разлики между документи или между различни версии на тях, можете да използвате Aspose.Words за сравняване на документи и получаване на промени в съдържанието във форматиране, заглавна/крака, таблици и др.

Тази статия обяснява как да се сравняват документи и как да се определят напредналите сравняващи свойства.

Ограничения и поддържани файлови формати

Сравняването на документи е много сложна характеристика. Има различни части на съдържание комбинация, която трябва да се анализира, за да се признае всички разлики. Причината за тази сложност се дължи на факта, че Aspose.Words цели да получи същите резултати от сравнение като Microsoft Word алгоритъм за сравнение.

Общото ограничение за два документа, които се сравняват, е, че те не трябва да имат ревизии, преди да се нарече метод за сравнение, тъй като това ограничение съществува в Microsoft Word.

Сравняване на две документи

Когато сравнявате документите, разликите в последния документ от първия се появяват като ревизии към предишния. Когато промените даден документ, всяка редакция ще има своя собствена ревизия след изпълнение на метода за сравнение.

Aspose.Words ви позволява да идентифицирате разликите в документите с помощта на Compare метод. . това е подобно на Microsoft Word функция за сравняване на документи. Тя ви позволява да проверявате документи или версии на документи, за да откриете разлики и промени, включително форматиране на модификации като промени в шрифта, промени в разстоянието, добавяне на думи и параграфи.

В резултат на сравнението документите могат да бъдат определени като равни или неравни. Терминът “документи с равно третиране” означава, че методът за сравнение не е в състояние да представя промените като ревизии. Това означава, че форматирането на текст и текст е еднакво. Но може да има и други различия между документите. Например, Microsoft Word поддържа само формат за ревизии за стилове и не можете да представлявате стил за вмъкване/изтриване. Така документите могат да имат различен набор от стилове и Compare метод все още не произвежда ревизии.

Следният пример за код показва как да се провери дали два документа са равни или не:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document docA = new Document(dataDir + "TestFile.doc");
Document docB = new Document(dataDir + "TestFile - Copy.doc");
// DocA now contains changes as revisions.
docA.Compare(docB, "user", DateTime.Now);
if (docA.Revisions.Count == 0)
Console.WriteLine("Documents are equal");
else
Console.WriteLine("Documents are not equal");

Следният пример с код показва как просто да се приложи Compare метод на два документа:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
// The source document doc1.
Document doc1 = new Document();
DocumentBuilder builder = new DocumentBuilder(doc1);
builder.Writeln("This is the original document.");
// The target document doc2.
Document doc2 = new Document();
builder = new DocumentBuilder(doc2);
builder.Writeln("This is the edited document.");
// If either document has a revision, an exception will be thrown.
if (doc1.Revisions.Count == 0 && doc2.Revisions.Count == 0)
doc1.Compare(doc2, "authorName", DateTime.Now);
// If doc1 and doc2 are different, doc1 now has some revisions after the comparison, which can now be viewed and processed.
Assert.AreEqual(2, doc1.Revisions.Count);
foreach (Revision r in doc1.Revisions)
{
Console.WriteLine($"Revision type: {r.RevisionType}, on a node of type \"{r.ParentNode.NodeType}\"");
Console.WriteLine($"\tChanged text: \"{r.ParentNode.GetText()}\"");
}
// All the revisions in doc1 are differences between doc1 and doc2, so accepting them on doc1 transforms doc1 into doc2.
doc1.Revisions.AcceptAll();
// doc1, when saved, now resembles doc2.
doc1.Save(dataDir + "Document.Compare.docx");
doc1 = new Document(dataDir + "Document.Compare.docx");
Assert.AreEqual(0, doc1.Revisions.Count);
Assert.AreEqual(doc2.GetText().Trim(), doc1.GetText().Trim());

Посочване на опциите за предварителни сравнения

Има много различни свойства на CompareOptions клас, който можете да приложите, когато искате да сравните документи.

Например, Aspose.Words ви позволява да игнорирате промените, направени по време на операция за сравнение за определени видове обекти в рамките на оригиналния документ. Можете да изберете подходящото свойство за типа обект, като IgnoreHeadersAndFooters, IgnoreFormatting, IgnoreComments, и други, като ги поставите “true”

Освен това, Aspose.Words осигурява Granularity собственост, с която можете да посочите дали да следите промените по характер или по дума.

Друг общ имот е изборът, в който документът да покаже промените в сравнението. Например, в кутията за диалог с документите Microsoft Word има опцията “Покажи промените в” това също се отразява на резултатите от сравнението. Aspose.Words осигурява Target собственост, която служи на тази цел.

Следният пример за код показва как да зададете напреднали сравняващи свойства:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
// Create the original document.
Document docOriginal = new Document();
DocumentBuilder builder = new DocumentBuilder(docOriginal);
// Insert paragraph text with an endnote.
builder.Writeln("Hello world! This is the first paragraph.");
builder.InsertFootnote(FootnoteType.Endnote, "Original endnote text.");
// Insert a table.
builder.StartTable();
builder.InsertCell();
builder.Write("Original cell 1 text");
builder.InsertCell();
builder.Write("Original cell 2 text");
builder.EndTable();
// Insert a textbox.
Shape textBox = builder.InsertShape(ShapeType.TextBox, 150, 20);
builder.MoveTo(textBox.FirstParagraph);
builder.Write("Original textbox contents");
// Insert a DATE field.
builder.MoveTo(docOriginal.FirstSection.Body.AppendParagraph(""));
builder.InsertField(" DATE ");
// Insert a comment.
Comment newComment = new Comment(docOriginal, "John Doe", "J.D.", DateTime.Now);
newComment.SetText("Original comment.");
builder.CurrentParagraph.AppendChild(newComment);
// Insert a header.
builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
builder.Writeln("Original header contents.");
// Create a clone of our document, which we will edit and later compare to the original.
Document docEdited = (Document)docOriginal.Clone(true);
Paragraph firstParagraph = docEdited.FirstSection.Body.FirstParagraph;
// Change the formatting of the first paragraph, change casing of original characters and add text.
firstParagraph.Runs[0].Text = "hello world! this is the first paragraph, after editing.";
firstParagraph.ParagraphFormat.Style = docEdited.Styles[StyleIdentifier.Heading1];
// Edit the footnote.
Footnote footnote = (Footnote)docEdited.GetChild(NodeType.Footnote, 0, true);
footnote.FirstParagraph.Runs[1].Text = "Edited endnote text.";
// Edit the table.
Table table = (Table)docEdited.GetChild(NodeType.Table, 0, true);
table.FirstRow.Cells[1].FirstParagraph.Runs[0].Text = "Edited Cell 2 contents";
// Edit the textbox.
textBox = (Shape)docEdited.GetChild(NodeType.Shape, 0, true);
textBox.FirstParagraph.Runs[0].Text = "Edited textbox contents";
// Edit the DATE field.
FieldDate fieldDate = (FieldDate)docEdited.Range.Fields[0];
fieldDate.UseLunarCalendar = true;
// Edit the comment.
Comment comment = (Comment)docEdited.GetChild(NodeType.Comment, 0, true);
comment.FirstParagraph.Runs[0].Text = "Edited comment.";
// Edit the header.
docEdited.FirstSection.HeadersFooters[HeaderFooterType.HeaderPrimary].FirstParagraph.Runs[0].Text = "Edited header contents.";
// Apply different comparing options.
CompareOptions compareOptions = new CompareOptions();
compareOptions.IgnoreFormatting = false;
compareOptions.IgnoreCaseChanges = false;
compareOptions.IgnoreComments = false;
compareOptions.IgnoreTables = false;
compareOptions.IgnoreFields = false;
compareOptions.IgnoreFootnotes = false;
compareOptions.IgnoreTextboxes = false;
compareOptions.IgnoreHeadersAndFooters = false;
compareOptions.Target = ComparisonTargetType.New;
// compare both documents.
docOriginal.Compare(docEdited, "John Doe", DateTime.Now, compareOptions);
docOriginal.Save(dataDir + "Document.CompareOptions.docx");
docOriginal = new Document(dataDir + "Document.CompareOptions.docx");
// If you set compareOptions to ignore certain types of changes,
// then revisions done on those types of nodes will not appear in the output document.
// You can tell what kind of node a revision was done on by looking at the NodeType of the revision's parent nodes.
Assert.AreNotEqual(compareOptions.IgnoreFormatting, docOriginal.Revisions.Any(rev => rev.RevisionType == RevisionType.FormatChange));
Assert.AreNotEqual(compareOptions.IgnoreCaseChanges, docOriginal.Revisions.Any(s => s.ParentNode.GetText().Contains("hello")));
Assert.AreNotEqual(compareOptions.IgnoreComments, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.Comment)));
Assert.AreNotEqual(compareOptions.IgnoreTables, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.Table)));
Assert.AreNotEqual(compareOptions.IgnoreFields, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.FieldStart)));
Assert.AreNotEqual(compareOptions.IgnoreFootnotes, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.Footnote)));
Assert.AreNotEqual(compareOptions.IgnoreTextboxes, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.Shape)));
Assert.AreNotEqual(compareOptions.IgnoreHeadersAndFooters, docOriginal.Revisions.Any(rev => HasParentOfType(rev, NodeType.HeaderFooter)));