Aspose.Words Document Object Model (DOM)

Aspose.Words Document Object Model (DOM) là bản trình bày trong bộ nhớ của tài liệu Word. Aspose.Words DOM cho phép bạn đọc, thao tác và sửa đổi nội dung cũng như định dạng của tài liệu Word theo chương trình.

Phần này mô tả các lớp chính của Aspose.Words DOM và mối quan hệ của chúng. Bằng cách sử dụng các lớp Aspose.Words DOM, bạn có thể có được quyền truy cập theo chương trình vào các thành phần và định dạng tài liệu.

Tạo cây đối tượng Document

Khi một tài liệu được đọc vào Aspose.Words DOM, thì một cây đối tượng sẽ được xây dựng và các loại phần tử khác nhau của tài liệu nguồn sẽ có các đối tượng cây DOM riêng với các thuộc tính khác nhau.

Xây dựng cây nút tài liệu

Khi Aspose.Words đọc tài liệu Word vào bộ nhớ, nó sẽ tạo các đối tượng thuộc các loại khác nhau đại diện cho các thành phần tài liệu khác nhau. Mỗi lần chạy văn bản, đoạn văn, bảng hoặc phần đều là một nút và thậm chí bản thân tài liệu cũng là một nút. Aspose.Words định nghĩa một lớp cho mọi loại nút tài liệu.

Cây tài liệu trong Aspose.Words tuân theo Mẫu thiết kế tổng hợp:

  • Cuối cùng, tất cả các lớp nút đều xuất phát từ lớp Node, đây là lớp cơ sở trong Aspose.Words Document Object Model.
  • Các nút có thể chứa các nút khác, ví dụ Section hoặc Paragraph, xuất phát từ lớp CompositeNode, sau đó lại xuất phát từ lớp Node.

Sơ đồ được cung cấp bên dưới hiển thị tính kế thừa giữa các lớp nút của Aspose.Words Document Object Model (DOM). Tên của các lớp trừu tượng được in nghiêng.

giả định từ-dom

Hãy xem một ví dụ. Hình ảnh sau đây hiển thị tài liệu Microsoft Word với các loại nội dung khác nhau.

tài liệu-ví dụ-aspose-words

Khi đọc tài liệu trên vào Aspose.Words DOM, cây đối tượng sẽ được tạo, như thể hiện trong lược đồ bên dưới.

dom-aspose-từ

Document, Section, Paragraph, Table, Shape, Run và tất cả các hình elip khác trên sơ đồ là các đối tượng Aspose.Words đại diện cho các thành phần của tài liệu Word.

Nhận {#get-a-node-type} loại Node

Mặc dù lớp Node đủ để phân biệt các nút khác nhau, Aspose.Words cung cấp bảng liệt kê NodeType để đơn giản hóa một số tác vụ API, chẳng hạn như chọn các nút thuộc một loại cụ thể.

Loại của mỗi nút có thể được lấy bằng thuộc tính NodeType. Thuộc tính này trả về giá trị liệt kê NodeType. Ví dụ: nút đoạn văn được biểu thị bằng lớp Paragraph trả về NodeType.Paragraph và nút bảng được biểu thị bằng lớp Table trả về NodeType.Table.

Ví dụ sau đây cho thấy cách lấy loại nút bằng cách sử dụng bảng liệt kê NodeType:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
// Returns NodeType.Document
NodeType type = doc.NodeType;

Điều hướng cây tài liệu

Aspose.Words thể hiện tài liệu dưới dạng cây nút, cho phép bạn điều hướng giữa các nút. Phần này mô tả cách khám phá và điều hướng cây tài liệu trong Aspose.Words.

Khi bạn mở tài liệu mẫu được trình bày trước đó trong Document Explorer, cây nút sẽ xuất hiện chính xác như được thể hiện trong Aspose.Words.

tài liệu trong tài liệu-explorer

Mối quan hệ nút tài liệu

Các nút trong cây có mối quan hệ giữa chúng:

  • Nút chứa nút khác là parent.
  • Nút chứa trong nút cha là nút child.. Các nút con của cùng nút cha là nút sibling.
  • Nút root luôn là nút Document.

Các nút có thể chứa các nút khác xuất phát từ lớp CompositeNode và tất cả các nút cuối cùng đều xuất phát từ lớp Node. Hai lớp cơ sở này cung cấp các phương thức và thuộc tính chung cho việc điều hướng và sửa đổi cấu trúc cây.

Sơ đồ đối tượng UML sau đây hiển thị một số nút của tài liệu mẫu và mối quan hệ của chúng với nhau thông qua các thuộc tính cha, con và anh chị em:

tài liệu-nút-mối quan hệ-aspose-từ

Tài liệu là chủ sở hữu nút

Một nút luôn thuộc về một tài liệu cụ thể, ngay cả khi nó vừa được tạo hoặc bị xóa khỏi cây, vì các cấu trúc quan trọng trên toàn tài liệu như kiểu và danh sách được lưu trữ trong nút Document. Ví dụ: không thể có Paragraph mà không có Document vì mỗi đoạn có một kiểu được chỉ định được xác định chung cho tài liệu. Quy tắc này được sử dụng khi tạo bất kỳ nút mới nào. Việc thêm trực tiếp Paragraph mới vào DOM yêu cầu một đối tượng tài liệu được chuyển đến hàm tạo.

Khi tạo một đoạn mới bằng DocumentBuilder, trình tạo luôn có lớp Document được liên kết với nó thông qua thuộc tính DocumentBuilder.Document.

Ví dụ mã sau đây cho thấy rằng khi tạo bất kỳ nút nào, tài liệu sẽ sở hữu nút đó luôn được xác định:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
// Open a file from disk.
Document doc = new Document();
// Creating a new node of any type requires a document passed into the constructor.
Paragraph para = new Paragraph(doc);
// The new paragraph node does not yet have a parent.
Console.WriteLine("Paragraph has no parent node: " + (para.ParentNode == null));
// But the paragraph node knows its document.
Console.WriteLine("Both nodes' documents are the same: " + (para.Document == doc));
// The fact that a node always belongs to a document allows us to access and modify
// Properties that reference the document-wide data such as styles or lists.
para.ParagraphFormat.StyleName = "Heading 1";
// Now add the paragraph to the main text of the first section.
doc.FirstSection.Body.AppendChild(para);
// The paragraph node is now a child of the Body node.
Console.WriteLine("Paragraph has a parent node: " + (para.ParentNode != null));

Nút gốc

Mỗi nút có một nút cha được chỉ định bởi thuộc tính ParentNode. Một nút không có nút cha, nghĩa là ParentNode là null, trong các trường hợp sau:

  • Nút vừa được tạo và chưa được thêm vào cây.
  • Nút đã bị xóa khỏi cây.
  • Đây là nút Document gốc luôn có nút cha rỗng.

Bạn có thể xóa một nút khỏi nút cha của nó bằng cách gọi phương thức Remove. Ví dụ mã sau đây cho biết cách truy cập nút cha:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
// Create a new empty document. It has one section.
Document doc = new Document();
// The section is the first child node of the document.
Node section = doc.FirstChild;
// The section's parent node is the document.
Console.WriteLine("Section parent is the document: " + (doc == section.ParentNode));

Nút con

Cách hiệu quả nhất để truy cập các nút con của CompositeNode là thông qua các thuộc tính FirstChildLastChild tương ứng trả về các nút con đầu tiên và cuối cùng. Nếu không có nút con, các thuộc tính này trả về null.

CompositeNode cũng cung cấp phương thức GetChildNodes cho phép truy cập được lập chỉ mục hoặc liệt kê vào các nút con. Thuộc tính ChildNodes là một tập hợp trực tiếp các nút, có nghĩa là bất cứ khi nào tài liệu được thay đổi, chẳng hạn như khi các nút được xóa hoặc thêm vào, bộ sưu tập ChildNodes sẽ tự động được cập nhật.

Nếu một nút không có nút con thì thuộc tính ChildNodes sẽ trả về một bộ sưu tập trống. Bạn có thể kiểm tra xem CompositeNode có chứa bất kỳ nút con nào hay không bằng thuộc tính HasChildNodes.

Ví dụ về mã sau đây cho thấy cách liệt kê các nút con trực tiếp của CompositeNode bằng cách sử dụng bộ liệt kê do bộ sưu tập ChildNodes cung cấp:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
Paragraph paragraph = (Paragraph)doc.GetChild(NodeType.Paragraph, 0, true);
NodeCollection children = paragraph.ChildNodes;
foreach (Node child in children)
{
// Paragraph may contain children of various types such as runs, shapes and so on.
if (child.NodeType.Equals(NodeType.Run))
{
// Say we found the node that we want, do something useful.
Run run = (Run)child;
Console.WriteLine(run.Text);
}
}

Ví dụ về mã sau đây cho thấy cách liệt kê các nút con ngay lập tức của CompositeNode bằng cách sử dụng quyền truy cập được lập chỉ mục:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
Paragraph paragraph = (Paragraph)doc.GetChild(NodeType.Paragraph, 0, true);
NodeCollection children = paragraph.ChildNodes;
for (int i = 0; i < children.Count; i++)
{
Node child = children[i];
// Paragraph may contain children of various types such as runs, shapes and so on.
if (child.NodeType.Equals(NodeType.Run))
{
// Say we found the node that we want, do something useful.
Run run = (Run)child;
Console.WriteLine(run.Text);
}
}

Nút anh chị em

Bạn có thể lấy nút ngay trước hoặc sau một nút cụ thể bằng cách sử dụng thuộc tính PreviousSiblingNextSibling tương ứng. Nếu một nút là nút con cuối cùng của nút cha thì thuộc tính NextSiblingnull. Ngược lại, nếu nút là con đầu tiên của nút cha thì thuộc tính PreviousSiblingnull.

Ví dụ mã sau đây cho thấy cách truy cập hiệu quả tất cả các nút con trực tiếp và gián tiếp của nút tổng hợp:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
public static void RecurseAllNodes()
{
// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_WorkingWithNode();
// Open a document.
Document doc = new Document(dataDir + "Node.RecurseAllNodes.doc");
// Invoke the recursive function that will walk the tree.
TraverseAllNodes(doc);
}
/// <summary>
/// A simple function that will walk through all children of a specified node recursively
/// And print the type of each node to the screen.
/// </summary>
public static void TraverseAllNodes(CompositeNode parentNode)
{
// This is the most efficient way to loop through immediate children of a node.
for (Node childNode = parentNode.FirstChild; childNode != null; childNode = childNode.NextSibling)
{
// Do some useful work.
Console.WriteLine(Node.NodeTypeToString(childNode.NodeType));
// Recurse into the node if it is a composite node.
if (childNode.IsComposite)
TraverseAllNodes((CompositeNode)childNode);
}
}

Đã nhập quyền truy cập vào nút con và nút cha

Cho đến nay, chúng ta đã thảo luận về các thuộc tính trả về một trong các loại cơ sở – Node hoặc CompositeNode. Nhưng đôi khi có những tình huống mà bạn có thể cần truyền các giá trị tới một lớp nút cụ thể, chẳng hạn như Run hoặc Paragraph. Nghĩa là, bạn không thể hoàn toàn thoát khỏi việc truyền khi làm việc với Aspose.Words DOM, là kết hợp.

Để giảm nhu cầu truyền, hầu hết các lớp Aspose.Words đều cung cấp các thuộc tính và bộ sưu tập cung cấp quyền truy cập được định kiểu mạnh. Có ba mẫu truy cập được gõ cơ bản:

  • Nút cha hiển thị các thuộc tính FirstXXXLastXXX đã nhập. Ví dụ: Document có các thuộc tính FirstSectionLastSection. Tương tự, Table có các thuộc tính như FirstRow, LastRow và các thuộc tính khác.
  • Nút cha hiển thị một tập hợp các nút con được đánh máy, chẳng hạn như Document.Sections, Body.Paragraphs và các nút khác.
  • Nút con cung cấp quyền truy cập được đánh máy vào nút cha của nó, chẳng hạn như Run.ParentParagraph, Paragraph.ParentSection và các nút khác.

Thuộc tính được nhập chỉ đơn thuần là các phím tắt hữu ích đôi khi cung cấp quyền truy cập dễ dàng hơn các thuộc tính chung được kế thừa từ Node.ParentNodeCompositeNode.FirstChild.

Ví dụ mã sau đây cho thấy cách sử dụng các thuộc tính đã nhập để truy cập các nút của cây tài liệu:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-.NET
Document doc = new Document();
Section section = doc.FirstSection;
// Quick typed access to the Body child node of the Section.
Body body = section.Body;
// Quick typed access to all Table child nodes contained in the Body.
TableCollection tables = body.Tables;
foreach (Table table in tables)
{
// Quick typed access to the first row of the table.
if (table.FirstRow != null)
table.FirstRow.Remove();
// Quick typed access to the last row of the table.
if (table.LastRow != null)
table.LastRow.Remove();
}