Aspose.Words Document Object Model (DOM)
Aspose.Words Document Object Model (DOM) เป็นตัวแทนในหน่วยความจำของเอกสาร Word Aspose.Words DOM ช่วยให้คุณสามารถอ่าน จัดการ และแก้ไขเนื้อหาและการจัดรูปแบบของเอกสาร Word โดยทางโปรแกรม
ส่วนนี้จะอธิบายคลาสหลักของ Aspose.Words DOM และความสัมพันธ์ โดยใช้คลาส Aspose.Words DOM คุณสามารถรับการเข้าถึงองค์ประกอบเอกสารและการจัดรูปแบบโดยทางโปรแกรม
สร้าง {#create-a-document-objects-tree} ทรีออบเจ็กต์ Document
เมื่ออ่านเอกสารลงใน Aspose.Words DOM แผนผังออบเจ็กต์จะถูกสร้างขึ้นและองค์ประกอบประเภทต่างๆ ของเอกสารต้นฉบับจะมีออบเจ็กต์แผนผัง DOM ของตัวเองที่มีคุณสมบัติต่างๆ
สร้างโครงสร้างโหนดเอกสาร
เมื่อ Aspose.Words อ่านเอกสาร Word ลงในหน่วยความจำ จะสร้างออบเจ็กต์ประเภทต่างๆ ที่แสดงถึงองค์ประกอบต่างๆ ของเอกสาร การเรียกใช้ข้อความ ย่อหน้า ตาราง หรือส่วนทุกครั้งถือเป็นโหนด และแม้แต่ตัวเอกสารเองก็คือโหนด Aspose.Words กำหนดคลาสสำหรับโหนดเอกสารทุกประเภท
แผนผังเอกสารใน Aspose.Words เป็นไปตามรูปแบบการออกแบบคอมโพสิต:
- คลาสโหนดทั้งหมดได้รับมาจากคลาส Node ซึ่งเป็นคลาสพื้นฐานใน Aspose.Words Document Object Model ในที่สุด
- โหนดที่สามารถมีโหนดอื่นได้ เช่น Section หรือ Paragraph ได้มาจากคลาส CompositeNode ซึ่งในทางกลับกันก็มาจากคลาส Node
แผนภาพด้านล่างแสดงการสืบทอดระหว่างคลาสโหนดของ Aspose.Words Document Object Model (DOM) ชื่อของคลาสนามธรรมเป็นภาษาตัวเอียง

ลองดูตัวอย่าง รูปภาพต่อไปนี้แสดงเอกสาร Microsoft Word ที่มีเนื้อหาประเภทต่างๆ

เมื่ออ่านเอกสารด้านบนลงใน Aspose.Words DOM โครงสร้างของออบเจ็กต์จะถูกสร้างขึ้น ดังที่แสดงในสคีมาด้านล่าง

Document, Section, Paragraph, Table, Shape, Run และจุดไข่ปลาอื่นๆ ทั้งหมดในไดอะแกรมคือออบเจ็กต์ Aspose.Words ที่แสดงองค์ประกอบของเอกสาร Word
รับ {#get-a-node-type} ประเภท Node
แม้ว่าคลาส Node จะเพียงพอที่จะแยกแยะโหนดต่างๆ จากกัน แต่ Aspose.Words จัดเตรียมการแจงนับ NodeType เพื่อลดความซับซ้อนของงาน API บางอย่าง เช่น การเลือกโหนดประเภทเฉพาะ
สามารถรับประเภทของแต่ละโหนดได้โดยใช้คุณสมบัติ Node.node_type คุณสมบัตินี้ส่งกลับค่าการแจงนับ NodeType ตัวอย่างเช่น โหนดย่อหน้าที่แสดงโดยคลาส Paragraph จะส่งคืน NodeType.PARAGRAPH และโหนดตารางที่แสดงโดยคลาส Table จะส่งคืน NodeType.TABLE
ตัวอย่างต่อไปนี้แสดงวิธีรับประเภทโหนดโดยใช้การแจงนับ NodeType:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
type = doc.node_type |
การนำทางแผนผังเอกสาร
Aspose.Words แสดงถึงเอกสารเป็นแผนผังโหนด ซึ่งช่วยให้คุณนำทางระหว่างโหนดได้ ส่วนนี้อธิบายวิธีสำรวจและสำรวจโครงสร้างเอกสารใน Aspose.Words
เมื่อคุณเปิดเอกสารตัวอย่างที่แสดงไว้ก่อนหน้านี้ใน Document Explorer แผนผังโหนดจะปรากฏเหมือนกับที่แสดงใน Aspose.Words ทุกประการ

ความสัมพันธ์ของโหนดเอกสาร
โหนดในแผนผังมีความสัมพันธ์ระหว่างกัน:
- โหนดที่มีโหนดอื่นคือ parent.
- โหนดที่อยู่ในโหนดหลักคือโหนด child. Child ของโหนดหลักเดียวกันคือโหนด sibling
- โหนด root จะเป็นโหนด Document เสมอ
โหนดที่สามารถมีโหนดอื่นได้มาจากคลาส CompositeNode และโหนดทั้งหมดได้รับมาจากคลาส Node ในที่สุด คลาสพื้นฐานทั้งสองนี้มีวิธีการและคุณสมบัติทั่วไปสำหรับการนำทางและการปรับเปลี่ยนโครงสร้างต้นไม้
แผนภาพอ็อบเจ็กต์ UML ต่อไปนี้แสดงหลายโหนดของเอกสารตัวอย่างและความสัมพันธ์ระหว่างกันผ่านคุณสมบัติพาเรนต์ รายการย่อย และรายการพี่น้อง:

เอกสารเป็นเจ้าของโหนด
โหนดจะอยู่ในเอกสารใดเอกสารหนึ่งเสมอ แม้ว่าจะเพิ่งสร้างหรือลบออกจากแผนผังก็ตาม เนื่องจากโครงสร้างทั่วทั้งเอกสารที่สำคัญ เช่น สไตล์และรายการจะถูกจัดเก็บไว้ในโหนด Document ตัวอย่างเช่น เป็นไปไม่ได้ที่จะมี Paragraph โดยไม่มี Document เนื่องจากแต่ละย่อหน้ามีสไตล์ที่กำหนดซึ่งกำหนดไว้ทั่วโลกสำหรับเอกสาร กฎนี้ใช้เมื่อสร้างโหนดใหม่ การเพิ่ม Paragraph ใหม่โดยตรงไปยัง DOM ต้องใช้วัตถุเอกสารที่ส่งผ่านไปยังตัวสร้าง
เมื่อสร้างย่อหน้าใหม่โดยใช้ DocumentBuilder ตัวสร้างจะมีคลาส Document ที่เชื่อมโยงผ่านคุณสมบัติ DocumentBuilder.document เสมอ
ตัวอย่างโค้ดต่อไปนี้แสดงให้เห็นว่าเมื่อสร้างโหนดใด ๆ เอกสารที่จะเป็นเจ้าของโหนดจะถูกกำหนดเสมอ:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
# Creating a new node of any type requires a document passed into the constructor. | |
para = aw.Paragraph(doc) | |
# The new paragraph node does not yet have a parent. | |
print(f"Paragraph has no parent node: {para.parent_node == None}") | |
# But the paragraph node knows its document. | |
print(f"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.paragraph_format.style_name = "Heading 1" | |
# Now add the paragraph to the main text of the first section. | |
doc.first_section.body.append_child(para) | |
# The paragraph node is now a child of the Body node. | |
print(f"Paragraph has a parent node: {para.parent_node != None}") |
โหนดหลัก
แต่ละโหนดมีพาเรนต์ที่ระบุโดยคุณสมบัติ parent_node โหนดไม่มีโหนดหลัก นั่นคือ parent_node คือ None ในกรณีต่อไปนี้:
- โหนดเพิ่งถูกสร้างขึ้นและยังไม่ได้เพิ่มลงในแผนผัง
- โหนดถูกลบออกจากแผนผังแล้ว
- นี่คือโหนด Document รูทซึ่งมีโหนดพาเรนต์ไม่มีเสมอ
คุณสามารถลบโหนดออกจากพาเรนต์ได้โดยการเรียกเมธอด Node.remove ตัวอย่างโค้ดต่อไปนี้แสดงวิธีเข้าถึงโหนดพาเรนต์:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
# The section is the first child node of the document. | |
section = doc.first_child | |
# The section's parent node is the document. | |
print(f"Section parent is the document: {doc == section.parent_node}") |
โหนดย่อย
วิธีที่มีประสิทธิภาพที่สุดในการเข้าถึงโหนดลูกของ CompositeNode คือผ่านคุณสมบัติ first_child และ last_child ที่ส่งคืนโหนดลูกแรกและโหนดสุดท้ายตามลำดับ หากไม่มีโหนดย่อย คุณสมบัติเหล่านี้จะส่งคืน None
CompositeNode ยังมีคอลเลกชัน get_child_nodes ที่เปิดใช้งานการเข้าถึงโหนดย่อยแบบจัดทำดัชนีหรือแจกแจง เมธอด get_child_nodes ส่งคืนคอลเลกชันโหนดสด ซึ่งหมายความว่าเมื่อใดก็ตามที่เอกสารมีการเปลี่ยนแปลง เช่น เมื่อโหนดถูกลบหรือเพิ่ม คอลเลกชัน get_child_nodes จะได้รับการอัปเดตโดยอัตโนมัติ
หากโหนดไม่มีลูก วิธีการ get_child_nodes จะส่งกลับคอลเลกชันที่ว่างเปล่า คุณสามารถตรวจสอบว่า CompositeNode มีโหนดย่อยโดยใช้คุณสมบัติ has_child_nodes หรือไม่
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการระบุโหนดลูกในทันทีของ CompositeNode โดยใช้ตัวแจงนับที่มาจากคอลเลกชัน get_child_nodes:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
paragraph = doc.get_child(aw.NodeType.PARAGRAPH, 0, True).as_paragraph() | |
children = paragraph.child_nodes | |
for child in children : | |
# A paragraph may contain children of various types such as runs, shapes, and others. | |
if child.node_type == aw.NodeType.RUN : | |
run = child.as_run() | |
print(run.text) | |
โหนดพี่น้อง
คุณสามารถรับโหนดที่อยู่ข้างหน้าหรือตามโหนดใดโหนดหนึ่งได้ทันทีโดยใช้คุณสมบัติ previous_sibling และ next_sibling ตามลำดับ หากโหนดเป็นโหนดลูกสุดท้ายของพาเรนต์ คุณสมบัติ next_sibling จะเป็น None ในทางกลับกัน หากโหนดเป็นโหนดลูกแรกของโหนดหลัก คุณสมบัติ previous_sibling จะเป็น None
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการเยี่ยมชมโหนดลูกทั้งทางตรงและทางอ้อมของโหนดคอมโพสิตอย่างมีประสิทธิภาพ:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
def test_recurse_all_nodes(self) : | |
doc = aw.Document(docs_base.my_dir + "Paragraphs.docx") | |
# Invoke the recursive function that will walk the tree. | |
self.traverse_all_nodes(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> | |
def traverse_all_nodes(self, parentNode) : | |
# This is the most efficient way to loop through immediate children of a node. | |
for childNode in parentNode.child_nodes : | |
print(aw.Node.node_type_to_string(childNode.node_type)) | |
# Recurse into the node if it is a composite node. | |
if childNode.is_composite : | |
self.traverse_all_nodes(childNode.as_composite_node()) | |
พิมพ์การเข้าถึงโหนดลูกและผู้ปกครอง
จนถึงตอนนี้ เราได้พูดคุยถึงคุณสมบัติที่ส่งคืนประเภทฐานอย่างใดอย่างหนึ่ง – Node หรือ CompositeNode แต่บางครั้งมีสถานการณ์ที่คุณอาจต้องส่งค่าไปยังคลาสโหนดเฉพาะ เช่น Run หรือ Paragraph นั่นคือคุณไม่สามารถหลีกหนีจากการคัดเลือกนักแสดงได้อย่างสมบูรณ์เมื่อทำงานกับ Aspose.Words DOM ซึ่งเป็นแบบประกอบ
เพื่อลดความจำเป็นในการแคสต์ คลาส Aspose.Words ส่วนใหญ่จะมีคุณสมบัติและคอลเลกชั่นที่ให้การเข้าถึงแบบเข้มงวด การเข้าถึงด้วยการพิมพ์มีรูปแบบพื้นฐานสามรูปแบบ:
- โหนดพาเรนต์เปิดเผยคุณสมบัติ แรก_XXX และ สุดท้าย_XXX ที่พิมพ์ ตัวอย่างเช่น Document มีคุณสมบัติ first_section และ last_section ในทำนองเดียวกัน Table มีคุณสมบัติเช่น first_row, last_row และอื่นๆ
- โหนดพาเรนต์เปิดเผยคอลเลกชันที่พิมพ์ของโหนดย่อย เช่น Document.sections, Body.paragraphs และอื่นๆ
- โหนดย่อยให้การเข้าถึงแบบพิมพ์ไปยังพาเรนต์ เช่น Run.parent_paragraph, Paragraph.parent_section และอื่นๆ
คุณสมบัติที่พิมพ์เป็นเพียงทางลัดที่มีประโยชน์ซึ่งบางครั้งให้การเข้าถึงได้ง่ายกว่าคุณสมบัติทั่วไปที่สืบทอดมาจาก Node.parent_node และ CompositeNode.first_child
ตัวอย่างรหัสต่อไปนี้แสดงวิธีการใช้คุณสมบัติที่พิมพ์เพื่อเข้าถึงโหนดของโครงสร้างเอกสาร:
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
section = doc.first_section | |
body = section.body | |
# Quick typed access to all Table child nodes contained in the Body. | |
tables = body.tables | |
for table in tables : | |
# Quick typed access to the first row of the table. | |
if table.first_row != None : | |
table.first_row.remove() | |
# Quick typed access to the last row of the table. | |
if table.last_row != None : | |
table.last_row.remove() | |