Порівняння документів

Порівняння документів-це процес, який ідентифікує зміни між двома документами та містить зміни у вигляді ревізій. Цей процес порівнює будь-які два документи, включаючи версії одного конкретного документа, після чого зміни між обома документами будуть показані як перегляди в першому документі.

Метод порівняння досягається шляхом порівняння слів на рівні символів або на рівні слова. Якщо в слові змінено хоча б один символ, в результаті різниця відображатиметься як зміна всього слова, а не символу. Цей процес порівняння є звичайним завданням у юридичній та фінансовій галузях.

Замість того, щоб вручну шукати відмінності між документами або їх версіями, ви можете використовувати 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-C
System::SharedPtr<Document> docA = System::MakeObject<Document>(inputDataDir + u"TestFile.doc");
System::SharedPtr<Document> docB = System::MakeObject<Document>(inputDataDir + u"TestFile - Copy.doc");
// DocA now contains changes as revisions.
docA->Compare(docB, u"user", System::DateTime::get_Now());
if (docA->get_Revisions()->get_Count() == 0)
{
std::cout << "Documents are equal" << std::endl;
}
else
{
std::cout << "Documents are not equal" << std::endl;
}

Наступний приклад коду показує, як просто застосувати метод Compare до двох документів:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// The source document doc1
System::SharedPtr<Document> doc1 = System::MakeObject<Document>();
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc1);
builder->Writeln(u"This is the original document.");
// The target document doc2
System::SharedPtr<Document> doc2 = System::MakeObject<Document>();
builder = System::MakeObject<DocumentBuilder>(doc2);
builder->Writeln(u"This is the edited document.");
// If either document has a revision, an exception will be thrown
if (doc1->get_Revisions()->get_Count() == 0 && doc2->get_Revisions()->get_Count() == 0)
doc1->Compare(doc2, u"authorName", System::DateTime::get_Now());
// If doc1 and doc2 are different, doc1 now has some revisions after the comparison, which can now be viewed and processed
if (doc1->get_Revisions()->get_Count() == 2)
std::cout << "Documents are equal." << std::endl << std::endl;
for (System::SharedPtr<Revision> r : System::IterateOver(doc1->get_Revisions()))
{
std::cout << "Revision type: " << System::ObjectExt::ToString(r->get_RevisionType()).ToUtf8String()
<< ", on a node of type " << System::ObjectExt::ToString(r->get_ParentNode()->get_NodeType()).ToUtf8String() << std::endl;
std::cout << "Changed text: " << r->get_ParentNode()->GetText() << std::endl;
}
// All the revisions in doc1 are differences between doc1 and doc2, so accepting them on doc1 transforms doc1 into doc2
doc1->get_Revisions()->AcceptAll();
// doc1, when saved, now resembles doc2
doc1->Save(inputDataDir + u"Document.Compare.docx");
doc1 = System::MakeObject<Document>(inputDataDir + u"Document.Compare.docx");
if (doc1->get_Revisions()->get_Count() == 0)
std::cout << "Documents are equal" << std::endl;
if (doc2->GetText().Trim() == doc1->GetText().Trim())
std::cout << "Documents are equal" << std::endl;

Вкажіть додаткові параметри порівняння

Існує багато різних властивостей класу 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-C
// Create the original document
System::SharedPtr<Document> docOriginal = System::MakeObject<Document>();
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(docOriginal);
// Insert paragraph text with an endnote
builder->Writeln(u"Hello world! This is the first paragraph.");
builder->InsertFootnote(FootnoteType::Endnote, u"Original endnote text.");
// Insert a table
builder->StartTable();
builder->InsertCell();
builder->Write(u"Original cell 1 text");
builder->InsertCell();
builder->Write(u"Original cell 2 text");
builder->EndTable();
// Insert a textbox
System::SharedPtr<Shape> textBox = builder->InsertShape(ShapeType::TextBox, 150, 20);
builder->MoveTo(textBox->get_FirstParagraph());
builder->Write(u"Original textbox contents");
// Insert a DATE field
builder->MoveTo(docOriginal->get_FirstSection()->get_Body()->AppendParagraph(u""));
builder->InsertField(u" DATE ");
// Insert a comment
auto newComment = System::MakeObject<Comment>(docOriginal, u"John Doe", u"J.D.", System::DateTime::get_Now());
newComment->SetText(u"Original comment.");
builder->get_CurrentParagraph()->AppendChild(newComment);
// Insert a header
builder->MoveToHeaderFooter(Aspose::Words::HeaderFooterType::HeaderPrimary);
builder->Writeln(u"Original header contents.");
// Create a clone of our document, which we will edit and later compare to the original
auto docEdited = System::DynamicCast<Aspose::Words::Document>(System::StaticCast<Node>(docOriginal)->Clone(true));
System::SharedPtr<Paragraph> firstParagraph = docEdited->get_FirstSection()->get_Body()->get_FirstParagraph();
// Change the formatting of the first paragraph, change casing of original characters and add text
firstParagraph->get_Runs()->idx_get(0)->set_Text(u"hello world! this is the first paragraph, after editing.");
firstParagraph->get_ParagraphFormat()->set_Style(docEdited->get_Styles()->idx_get(Aspose::Words::StyleIdentifier::Heading1));
// Edit the footnote
auto footnote = System::DynamicCast<Aspose::Words::Footnote>(docEdited->GetChild(Aspose::Words::NodeType::Footnote, 0, true));
footnote->get_FirstParagraph()->get_Runs()->idx_get(1)->set_Text(u"Edited endnote text.");
// Edit the table
auto table = System::DynamicCast<Aspose::Words::Tables::Table>(docEdited->GetChild(Aspose::Words::NodeType::Table, 0, true));
table->get_FirstRow()->get_Cells()->idx_get(1)->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited Cell 2 contents");
// Edit the textbox
textBox = System::DynamicCast<Aspose::Words::Drawing::Shape>(docEdited->GetChild(Aspose::Words::NodeType::Shape, 0, true));
textBox->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited textbox contents");
// Edit the DATE field
auto fieldDate = System::DynamicCast<Aspose::Words::Fields::FieldDate>(docEdited->get_Range()->get_Fields()->idx_get(0));
fieldDate->set_UseLunarCalendar(true);
// Edit the comment
auto comment = System::DynamicCast<Aspose::Words::Comment>(docEdited->GetChild(Aspose::Words::NodeType::Comment, 0, true));
comment->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited comment.");
// Edit the header
docEdited->get_FirstSection()->get_HeadersFooters()->idx_get(Aspose::Words::HeaderFooterType::HeaderPrimary)->get_FirstParagraph()->get_Runs()->idx_get(0)->set_Text(u"Edited header contents.");
// When we compare documents, the differences of the latter document from the former show up as revisions to the former
// Each edit that we've made above will have its own revision, after we run the Compare method
// We can compare with a CompareOptions object, which can suppress changes done to certain types of objects within the original document
// from registering as revisions after the comparison by setting some of these members to "true"
auto compareOptions = System::MakeObject<Aspose::Words::CompareOptions>();
compareOptions->set_IgnoreFormatting(false);
compareOptions->set_IgnoreCaseChanges(false);
compareOptions->set_IgnoreComments(false);
compareOptions->set_IgnoreTables(false);
compareOptions->set_IgnoreFields(false);
compareOptions->set_IgnoreFootnotes(false);
compareOptions->set_IgnoreTextboxes(false);
compareOptions->set_IgnoreHeadersAndFooters(false);
compareOptions->set_Target(Aspose::Words::ComparisonTargetType::New);
docOriginal->Compare(docEdited, u"John Doe", System::DateTime::get_Now(), compareOptions);
docOriginal->Save(inputDataDir + u"Document.CompareOptions.docx");