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 bản 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 bản 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ừ có sự thay đổi của ít nhất một ký tự thì 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 một ký tự. Quá trình so sánh này là một nhiệm vụ thông thường trong ngành pháp lý và tài chính.
Thay vì tìm kiếm 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 theo cách thủ công, bạn có thể sử dụng Aspose.Words để so sánh các tài liệu và nhận các thay đổi về nội dung trong định dạng, đầu trang/chân trang, bảng, v.v.
Bài viết này giải thích cách so sánh tài liệu và cách chỉ định các thuộc tính so sánh nâng cao.
Thử trực tuyến
Bạn có thể so sánh trực tuyến hai tài liệu bằng cách sử dụng công cụ So sánh tài liệu trực tuyến.
Lưu ý rằng phương pháp so sánh được mô tả bên dưới được sử dụng trong công cụ này để đảm bảo nhận được kết quả như nhau. Vì vậy, bạn sẽ nhận được kết quả tương tự ngay cả khi sử dụng công cụ so sánh trực tuyến hoặc sử dụng phương pháp so sánh trong Aspose.Words.
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 hướng tới mục tiêu đạt được kết quả so sánh giống như thuật toán so sánh Microsoft Word.
Hạn chế chung đối với hai tài liệu được so sánh là chúng không được có bản sửa đổi trước khi gọi phương thức so sánh vì hạn chế 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, những điểm khác biệt giữa tài liệu sau và tài liệu trước sẽ hiển thị dưới dạng bản sửa đổi so với tài liệu trước. Khi bạn sửa đổi một tài liệu, mỗi lần 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 pháp Compare - phương pháp 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 tài liệu hoặc phiên bản tài liệu để tìm ra sự khác biệt và thay đổi, bao gồm sửa đổi định dạng như thay đổi phông chữ, thay đổi khoảng cách, thêm từ và đoạn văn.
Qua so sánh có thể xác định các tài liệu bằng nhau hoặc không bằng nhau. Thuật ngữ tài liệu “bằng nhau” có nghĩa là phương pháp so sánh không thể biểu thị các thay đổi dưới dạng sửa đổi. Điều này có nghĩa là cả văn bản tài liệu và định dạng 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ợ các bản sửa đổi định dạng cho kiểu và bạn không thể biểu thị việc chèn/xóa kiểu. Vì vậy, tài liệu có thể có một bộ kiểu khác nhau và phương pháp Compare vẫn không tạo ra bản sửa đổi nào.
Ví dụ mã sau đây cho biết 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-.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"); |
Ví dụ về mã sau đây cho thấy cách áp dụng phương pháp Compare
cho hai tài liệu một cách đơn giản:
// 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()); |
Chỉ định các 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 những thay đổi được thực hiện trong quá trình 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à các thuộc tính khác bằng cách đặt chúng thành “true”.
Ngoài ra, Aspose.Words còn 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 chung khác là sự lựa chọn trong đó tài liệu sẽ hiển thị các thay đổi so sánh. Ví dụ: “Hộp thoại so sánh 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 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-.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))); |