Aspose.Words Document Object Model (DOM)
Tập tin Aspose.Words Document Object Model (DOM) là biểu diễn bộ nhớ của một tài liệu Word. Hàm Aspose.Words DOM cho phép bạn đọc, thao tác và sửa đổi nội dung và định dạng của một tài liệu Word bằng cách lập 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ể nhận được quyền truy cập lập trình vào các yếu tố tài liệu và định dạng.
Tạo Cây Đối Tượng Tài Liệu
Khi một tài liệu được đọc vào trong Aspose.Words DOM, sau đó một cây đối tượng được xây dựng và các loại phần tử khác nhau của tài liệu nguồn có các đối tượng cây DOM riêng với nhiều thuộc tính.
Xây dựng cây các nút tài liệu
Khi Aspose.Words đọc một tài liệu Word vào bộ nhớ, nó tạo ra các đối tượng của nhiều loại khác nhau để đại diện cho các yếu tố tài liệu khác nhau. Mỗi đoạn văn bản, đoạn văn, bảng hoặc phần là một nút và thậm chí cả 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 của tài liệu.
Cây tài liệu ở Aspose.Words tuân theo mẫu thiết kế Composite:
- Tất cả các lớp nút cuối cùng đều được thừa kế từ lớp Node, đó là lớp cơ sở trong Aspose.Words Document Object Model.
- Các node có thể chứa các node khác, ví dụ Section hay Paragraph thì xuất phát từ lớp CompositeNode, còn lại lại xuất phát từ lớp Node.
Biểu đồ dưới đây hiển thị sự thừa kế giữa các lớp của nút Aspose.Words Document Object Model (DOM). Tên của các lớp trừu tượng được viết bằng chữ nghiêng.

Node
.
Chúng ta hãy xem xét một ví dụ. Hình ảnh sau đây hiển thị một Microsoft Word với các loại nội dung khác nhau.

Khi đọc tài liệu ở trên vào phần Aspose.Words DOM, cây đối tượng được tạo ra như hình minh họa bên dưới.

Document, Section, Paragraph, Table, Shape, Run, và tất cả các dấu chấm chéo khác trên biểu đồ là Aspose.Words đối tượng đại diện cho các phần tử của tài liệu từ.
Nhận một Node
Loại
Loại của mỗi nút có thể được lấy bằng cách sử dụng thuộc tính NodeType. Tính chất này trả về giá trị của một NodeType. Ví dụ, một đoạn văn được thể hiện bởi lớp Paragraph trả về NodeType.Paragraph, và một bảng được thể hiện bởi lớp Table trả về NodeType.Table.
Ví dụ sau cho thấy cách lấy một kiểu nút bằng cách sử dụng NodeType enum:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
// Returns NodeType.Document | |
int type = doc.getNodeType(); |
Điều hướng Cây Tài liệu
Aspose.Words đại diện cho một tài liệu dưới dạng cây nút, điều này cho phép bạn di chuyển 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 giới thiệu trước đó trong Trình Xem Tài liệu, cây nút sẽ xuất hiện chính xác như nó được trình bày trong Aspose.Words.

Tóm tắt mối quan hệ tài liệu
Các nút trong cây có mối quan hệ giữa chúng
“- Một nút chứa một nút khác là parent.” The node chứa trong nút cha là child. Các nút con cùng một nút cha là sibling nút.
- Mối nút root luôn là mối nút Document.
Các node có thể chứa các node khác thì được thừa hưởng từ lớp CompositeNode, và tất cả các node đều thừa hưởng cuối cùng từ lớp Node. Những hai lớp cơ bản này cung cấp các phương pháp và thuộc tính chung cho việc điều hướng cấu trúc cây và sửa đổi.
Biểu đồ đối tượng UML sau cho thấy 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 mẹ, con và anh chị em

Tài liệu là Chủ sở hữu của nó
Điểm nào luôn thuộc về một tài liệu cụ thể, ngay cả khi nó mới được tạo hoặc xóa khỏi cây vì các cấu trúc quan trọng của tài liệu như kiểu và danh sách được lưu trữ trong Document điểm. Ví dụ, không thể có một Paragraph mà không có một Document vì mỗi đoạn văn có kiểu được định nghĩa toàn cục cho tài liệu. Quy tắc này được dùng khi tạo ra bất kỳ các node mới nào. Thêm một cái mới Paragraph trực tiếp vào DOM yêu cầu một đối tượng tài liệu được truyền đến trình tạo.
Khi tạo một đoạn văn mới bằng cách sử dụng DocumentBuilder, người xây dựng luôn có một lớp Document liên kết với nó thông qua thuộc tính DocumentBuilder.Document.
Ví dụ mã sau cho thấy khi tạo bất kỳ nút nào, một tài liệu sẽ sở hữu nút luôn được định nghĩa
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// 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. | |
System.out.println("Paragraph has no parent node: " + (para.getParentNode() == null)); | |
// But the paragraph node knows its document. | |
System.out.println("Both nodes' documents are the same: " + (para.getDocument() == 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.getParagraphFormat().setStyleName("Heading 1"); | |
// Now add the paragraph to the main text of the first section. | |
doc.getFirstSection().getBody().appendChild(para); | |
// The paragraph node is now a child of the Body node. | |
System.out.println("Paragraph has a parent node: " + (para.getParentNode() != null)); |
Node Cha
Mỗi nút có một bố được chỉ định bởi thuộc tính ParentNode. Một nút không có nút cha, tức là ParentNode là không có trong các trường hợp sau đây:
“- Nút đã mới được tạo và chưa còn thêm vào cây.”
- Node đã được xóa khỏi cây.
- Đây là nút gốc Document mà luôn có nút cha rỗng.
Bạn có thể loại bỏ một nút khỏi cha của nó bằng cách gọi phương thức Remove. Ví dụ mã sau cho thấy 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-Java | |
// 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.getFirstChild(); | |
// The section's parent node is the document. | |
System.out.println("Section parent is the document: " + (doc == section.getParentNode())); |
Node con
Cách hiệu quả nhất để truy cập các nút con của một CompositeNode là qua thuộc tính FirstChild và LastChild trả về các nút con đầu tiên và cuối cùng tương ứng. Nếu không có nút con, các thuộc tính này sẽ trả về null
CompositeNode cũng cung cấp bộ sưu tập ChildNodes cho phép truy cập được lập chỉ mục hoặc đếm số đến các nút con. Tính thuộc tính ChildNodes là một tập hợp các nút đang hoạt động, 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 bị xóa hoặc thêm, bộ sưu tập ChildNodes sẽ tự động được cập nhật.
Nếu một nút không có con, thuộc tính ChildNodes trả về một bộ sưu tập trống. Bạn có thể kiểm tra xem CompositeNode có chứa nút con nào không bằng cách dùng thuộc tính HasChildNodes.
Mã ví dụ sau cho thấy cách liệt kê các nút con ngay lập tức của một CompositeNode
bằng cách sử dụng bộ đếm được cung cấp bởi bộ sưu tập ChildNodes
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(dataDir + "Document.doc"); | |
Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); | |
NodeCollection children = paragraph.getChildNodes(); | |
for (Node child : (Iterable<Node>) children) { | |
// Paragraph may contain children of various types such as runs, shapes and so on. | |
if (child.getNodeType() == NodeType.RUN) { | |
// Say we found the node that we want, do something useful. | |
Run run = (Run) child; | |
System.out.println(run.getText()); | |
} | |
} |
Mã ví dụ sau cho thấy cách liệt kê các nút con ngay lập tức của một CompositeNode
sử dụng truy cập chỉ số:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(dataDir + "Document.doc"); | |
Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); | |
NodeCollection children = paragraph.getChildNodes(); | |
for (int i = 0; i < children.getCount(); i++) { | |
Node child = children.get(i); | |
// Paragraph may contain children of various types such as runs, shapes and so on. | |
if (child.getNodeType() == NodeType.RUN) { | |
// Say we found the node that we want, do something useful. | |
Run run = (Run) child; | |
System.out.println(run.getText()); | |
} | |
} |
Nodes anh chị em
Bạn có thể lấy nút mà ngay trước hoặc sau một nút cụ thể sử dụng thuộc tính PreviousSibling và NextSibling tương ứng. Nếu một nút là con cuối cùng của bố nó thì thuộc tính NextSibling là null. Ngược lại, nếu nút là con cái đầu tiên của nút cha, tính PreviousSibling thuộc tính là null.
Mã ví dụ sau 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 một nút hợp chất:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
public static void main(String[] args) throws Exception { | |
String dataDir = Utils.getSharedDataDir(ChildNodes.class) + "DocumentObjectModel/"; | |
recurseAllNodes(dataDir); | |
} | |
public static void recurseAllNodes(String dataDir) throws Exception { | |
// Open a document | |
Document doc = new Document(dataDir + "Node.RecurseAllNodes.doc"); | |
// Invoke the recursive function that will walk the tree. | |
traverseAllNodes(doc); | |
} | |
/** | |
* A simple function that will walk through all children of a specified node | |
* recursively and print the type of each node to the screen. | |
*/ | |
public static void traverseAllNodes(CompositeNode parentNode) throws Exception { | |
// This is the most efficient way to loop through immediate children of a node. | |
for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { | |
// Do some useful work. | |
System.out.println(Node.nodeTypeToString(childNode.getNodeType())); | |
// Recurse into the node if it is a composite node. | |
if (childNode.isComposite()) | |
traverseAllNodes((CompositeNode) childNode); | |
} | |
} |
Truy cập qua bàn phím vào nút con và nút cha
Cho đến nay chúng ta đã thảo luận về các tính chất mà trả về một trong các loại cơ bản – Node hoặc CompositeNode. Nhưng đôi khi có những tình huống mà bạn cần gán các giá trị đến một lớp nút cụ thể, chẳng hạn như Run hoặc Paragraph. Đó là, bạn không thể hoàn toàn thoát khỏi việc sử dụng các kiểu khi làm việc với Aspose.Words DOM, đó là đối tượng phức tạp.
Để giảm nhu cầu ghi đè, hầu hết các lớp Aspose.Words đều có thuộc tính và tập hợp cung cấp quyền truy cập kiểu mạnh. Có ba mẫu cơ bản của truy cập bằng bàn phím:
- A parent node exposes FirstXXX và LastXXX thuộc tính được gán kiểu. Ví dụ, Document có FirstSection và LastSection thuộc tính. Cũng vậy, Table có các đặc tính như FirstRow, LastRow và những thứ khác. “- A cha mẹ một nút phơi bày một tập hợp có kiểu của các nút con, chẳng hạn như Document.Sections, Body.Paragraphs và những người khác.” “- Một nút con cung cấp truy cập được gõ để cha của nó, chẳng hạn như Run.ParentParagraph, Paragraph.ParentSection và những người khác.”
Tính chất được gõ là những công cụ hữu ích chỉ cung cấp quyền truy cập dễ dàng hơn đôi khi so với các tính chất chung kế thừa từ Node.ParentNode và CompositeNode.FirstChild.
Mã ví dụ sau cho thấy cách sử dụng các thuộc tính được gõ để 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-Java | |
Document doc = new Document(); | |
// Quick typed access to the first child Section node of the Document. | |
Section section = doc.getFirstSection(); | |
// Quick typed access to the Body child node of the Section. | |
Body body = section.getBody(); | |
// Quick typed access to all Table child nodes contained in the Body. | |
TableCollection tables = body.getTables(); | |
for (Table table : tables) { | |
// Quick typed access to the first row of the table. | |
if (table.getFirstRow() != null) | |
table.getFirstRow().remove(); | |
// Quick typed access to the last row of the table. | |
if (table.getLastRow() != null) | |
table.getLastRow().remove(); | |
} |