So Sánh Tài Liệu

So sánh tài liệu là một quá trình xác định các thay đổi giữa hai tài liệu và chứa các thay đổi dưới dạng sửa đổi. Quá trình này so sánh hai tài liệu bất kỳ, bao gồm các phiên bản của một tài liệu cụ thể, sau đó những thay đổi giữa cả hai tài liệu sẽ được hiển thị dưới dạng sửa đổi trong tài liệu đầu tiên.

Phương pháp so sánh đạt được bằng cách so sánh các từ ở cấp độ ký tự hoặc cấp độ từ. Nếu một từ chứa thay đổi ít nhất một ký tự, trong kết quả, sự khác biệt sẽ được hiển thị dưới dạng thay đổi của toàn bộ từ chứ không phải ký tự. Quá trình so sánh này là một nhiệm vụ thông thường trong các ngành pháp lý và tài chính.

Thay vì tìm kiếm thủ công sự khác biệt giữa các tài liệu hoặc giữa các phiên bản khác nhau của chúng, bạn có thể sử dụng Aspose.Words để so sánh tài liệu và nhận các thay đổi nội dung về định dạng, tiêu đề/chân trang, bảng và hơn thế nữa.

Bài viết này giải thích cách so sánh tài liệu và cách chỉ định thuộc tính so sánh nâng cao.

Hạn chế Và Định dạng Tệp Được Hỗ trợ

So sánh tài liệu là một tính năng rất phức tạp. Có nhiều phần khác nhau của sự kết hợp nội dung cần được phân tích để nhận ra tất cả sự khác biệt. Lý do cho sự phức tạp này là do Aspose.Words nhằm mục đích nhận được kết quả so sánh tương tự như thuật toán so sánh Microsoft Word.

Giới hạn chung cho hai tài liệu được so sánh là chúng không được có sửa đổi trước khi gọi phương thức so sánh vì giới hạn này tồn tại trong Microsoft Word.

So Sánh Hai Tài Liệu

Khi bạn so sánh các tài liệu, sự khác biệt của tài liệu sau từ tài liệu trước hiển thị dưới dạng sửa đổi cho tài liệu trước. Khi bạn sửa đổi một tài liệu, mỗi chỉnh sửa sẽ có bản sửa đổi riêng sau khi chạy phương thức so sánh.

Aspose.Words cho phép bạn xác định sự khác biệt của tài liệu bằng phương thức Compare – điều này tương tự như tính năng so sánh tài liệu Microsoft Word. Nó cho phép bạn kiểm tra các tài liệu hoặc phiên bản tài liệu để tìm sự khác biệt và thay đổi, bao gồm các sửa đổi định dạng như thay đổi phông chữ, thay đổi khoảng cách, bổ sung các từ và đoạn văn.

Kết quả của việc so sánh, các tài liệu có thể được xác định là bằng hoặc không bằng nhau. Thuật ngữ tài liệu" bình đẳng " có nghĩa là phương pháp so sánh không thể biểu diễn các thay đổi dưới dạng sửa đổi. Điều này có nghĩa là cả định dạng văn bản tài liệu và văn bản đều giống nhau. Nhưng có thể có sự khác biệt khác giữa các tài liệu. Ví dụ: Microsoft Word chỉ hỗ trợ sửa đổi định dạng cho kiểu và bạn không thể biểu diễn chèn/xóa kiểu. Vì vậy, các tài liệu có thể có một tập hợp các kiểu khác nhau và phương thức Compare vẫn không tạo ra bản sửa đổi.

Ví dụ mã sau đây cho thấy cách kiểm tra xem hai tài liệu có bằng nhau hay không:

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;
}

Ví dụ mã sau đây cho thấy cách áp dụng phương thức Compare cho hai tài liệu:

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;

Chỉ Định Tùy Chọn So Sánh Nâng Cao

Có nhiều thuộc tính khác nhau của lớp CompareOptions mà bạn có thể áp dụng khi muốn so sánh tài liệu.

Ví dụ: Aspose.Words cho phép bạn bỏ qua các thay đổi được thực hiện trong thao tác so sánh đối với một số loại đối tượng nhất định trong tài liệu gốc. Bạn có thể chọn thuộc tính thích hợp cho loại đối tượng, chẳng hạn như IgnoreHeadersAndFooters, IgnoreFormatting, IgnoreComments, và những người khác bằng cách đặt chúng thành “đúng”.

Ngoài ra, Aspose.Words cung cấp thuộc tính Granularity mà bạn có thể chỉ định theo dõi các thay đổi theo ký tự hay theo từ.

Một thuộc tính phổ biến khác là sự lựa chọn trong đó tài liệu để hiển thị các thay đổi so sánh. Ví dụ: “So sánh hộp thoại tài liệu” trong Microsoft Word có tùy chọn “Hiển thị các thay đổi trong” – điều này cũng ảnh hưởng đến kết quả so sánh. Aspose.Words cung cấp thuộc tính Target phục vụ mục đích này.

Ví dụ mã sau đây cho thấy cách đặt các thuộc tính so sánh nâng cao:

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");