Aspose.Wordsรูปแบบวัตถุเอกสาร(DOM)

รูปแบบวัตถุเอกสารAspose.Words(DOM)เป็นตัวแทนในหน่วยความจำของเอกสารคำ Aspose.WordsDOMช่วยให้คุณสามารถอ่านจัดการและปรับเปลี่ยนเนื้อหาและการจัดรูปแบบของเอกสารคำ.

ส่วนนี้อธิบายชั้นเรียนหลักของAspose.WordsDOMและความสัมพันธ์ของชั้นเรียน โดยใช้ชั้นเรียนAspose.WordsDOMคุณสามารถขอรับการเข้าถึงแบบโปรแกรมไปยังองค์ประกอบของเอกสา.

สร้างต้นไม้วัตถุเอกสาร

เมื่อเอกสารถูกอ่านเข้าไปในAspose.WordsDOMจากนั้นต้นไม้วัตถุจะถูกสร้างขึ้นและชนิดขององค์ประกอบข.

สร้างต้นไม้โหนดเอกสาร

เมื่อAspose.Wordsอ่านเอกสารคำลงในหน่วยความจำจะสร้างวัตถุชนิดต่างๆที่แสดงถึงองค์ประกอบของเ รันของข้อความย่อหน้าตารางหรือส่วนทุกโหนดและแม้แต่เอกสารเองเป็นโหนด Aspose.Wordsกำหนดคลาสสำหรับทุกชนิดโหนดเอกสาร.

โครงสร้างเอกสารในAspose.Wordsตามรูปแบบการออกแบบคอมโพสิต:

  • คลาสโหนดทั้งหมดในที่สุดได้มาจากคลาสของNodeซึ่งเป็นคลาสฐานในโมเดลอ็อบเจ็กต์เอกสารAspose.Words.
  • โหนดที่สามารถประกอบด้วยโหนดอื่นเช่นSectionหรือParagraphได้มาจากคลาสของCompositeNodeซึ่งจะมาจากคลาสของNode.

แผนภาพที่ให้ไว้ด้านล่างแสดงการสืบทอดระหว่างคลาสโหนดของโมเดลออบเจกต์เอกสารAspose.Words(DOM) ชื่อของชั้นเรียนนามธรรมอยู่ในตัวเอียง.

aspose-words-dom-aspose-words-cpp

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

document-example-aspose-words-cpp

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

document-example-dom-aspose-words-cpp

Document, Section, Paragraph, Table, Shape, Run, และวงรีอื่นๆทั้งหมดในแผนภาพเป็นAspose.Wordsวัตถุที่แสดงถึงองค์ประกอบของเอกสารคำ.

รับNodeประเภท

แม้ว่าคลาส Node จะเพียงพอที่จะแยกแยะโหนดต่างๆ ออกจากกัน แต่ Aspose.Words ก็มีการแจงนับ NodeType เพื่อลดความซับซ้อนของงาน API บางอย่าง เช่น การเลือกโหนดประเภทเฉพาะ.

ชนิดของแต่ละโหนดสามารถรับได้โดยใช้คุณสมบัติNodeType คุณสมบัตินี้ส่งคืนNodeType enumeration value. For example, a paragraph node represented by the Paragraph class returns NodeType.Paragraphและโหนดตารางที่แสดงด้วยTable class returns NodeType.Table.

ตัวอย่างต่อไปนี้แสดงวิธีรับชนิดโหนดโดยใช้การแจงนับNodeType:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
System::SharedPtr<Document> doc = System::MakeObject<Document>();
// Returns NodeType.Document
NodeType type = doc->get_NodeType();

เอกสารต้นไม้นำทาง

Aspose.Wordsแทนเอกสารเป็นโหนดทรีซึ่งช่วยให้คุณสามารถนำทางระหว่างโหนด ส่วนนี้อธิบายวิธีสำรวจและนำทางแผนผังเอกสารในAspose.Words.

กสารแผนผังโหนดจะปรากฏตรงตามที่แสดงในAspose.Words.

document-in-document-explorer-aspose-words-cpp

ความสัมพันธ์ของโหนดเอกสาร

โหนดในต้นไม้มีความสัมพันธ์ระหว่างพวกเขา:

  • โหนดที่มีโหนดอื่นคือparent.
  • โหนดที่มีอยู่ในโหนดพาเรนต์คือโหนดลูกchild.ของพาเรนต์เดียวกันคือโหนดsibling.
  • โหนดrootคือโหนดDocumentเสมอ.

โหนดที่ประกอบด้วยโหนดอื่นได้มาจากคลาสของCompositeNodeและโหนดทั้งหมดได้มาจากคลาสของNode สองคลาสฐานมีวิธีการทั่วไปและคุณสมบัติสำหรับการนำทางโครงสร้างต้นไม้และการปรับ.

ไดอะแกรมออบเจกต์UMLต่อไปนี้แสดงโหนดหลายโหนดของเอกสารตัวอย่างและความสัมพันธ์:

document-nodes-relationships-aspose-words-cpp

เอกสารเป็นเจ้าของโหนด

กโครงสร้างทั้งเอกสารสำคัญเช่นลักษณะและรายการจะถูกเก็บไว้ในโหนด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-C
// Open a file from disk.
System::SharedPtr<Document> doc = System::MakeObject<Document>();
// Creating a new node of any type requires a document passed into the constructor.
System::SharedPtr<Paragraph> para = System::MakeObject<Paragraph>(doc);
// The new paragraph node does not yet have a parent.
std::cout << "Paragraph has no parent node: " << System::ObjectExt::Box<bool>((para->get_ParentNode() == nullptr))->ToString().ToUtf8String() << std::endl;
// But the paragraph node knows its document.
std::cout << "Both nodes' documents are the same: " << System::ObjectExt::Box<bool>((para->get_Document() == doc))->ToString().ToUtf8String() << std::endl;
// 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->get_ParagraphFormat()->set_StyleName(u"Heading 1");
// Now add the paragraph to the main text of the first section.
doc->get_FirstSection()->get_Body()->AppendChild(para);
// The paragraph node is now a child of the Body node.
std::cout << "Paragraph has a parent node: " << System::ObjectExt::Box<bool>((para->get_ParentNode() != nullptr))->ToString().ToUtf8String() << std::endl;

โหนดแม่

แต่ละโหนดมีพาเรนต์ที่ระบุโดยคุณสมบัติParentNode โหนดไม่มีโหนดพาเรนต์นั่นคือParentNodeเป็นโมฆะในกรณีต่อไปนี้:

  • โหนดเพิ่งถูกสร้างขึ้นและยังไม่ได้ถูกเพิ่มไปยังแผนผัง.
  • โหนดถูกเอาออกจากต้นไม้.
  • นี่คือโหนดรากDocumentซึ่งมักจะมีโหนดพาเรนต์โมฆะ.

คุณสามารถลบโหนดออกจากพาเรนต์ได้โดยเรียกวิธีการRemoveตัวอย่างรหัสต่อไปนี้แสดงวิธีการเข้าถึงโหนดพาเรนต์:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
// Create a new empty document. It has one section.
System::SharedPtr<Document> doc = System::MakeObject<Document>();
// The section is the first child node of the document.
System::SharedPtr<Node> section = doc->get_FirstChild();
// The section's parent node is the document.
std::cout << "Section parent is the document: " << System::ObjectExt::Box<bool>((doc == section->get_ParentNode()))->ToString().ToUtf8String() << std::endl;

โหนดเด็ก

วิธีที่มีประสิทธิภาพมากที่สุดในการเข้าถึงโหนดลูกของCompositeNodeคือผ่านคุณสมบัติFirstChildและLastChildที่ส่งคืนโหนดลูก หากไม่มีโหนดย่อยคุณสมบัติเหล่านี้จะกลับnull.

CompositeNode

ถ้าโหนดไม่มีลูกน้อยคุณสมบัติChildNodesจะส่งคืนคอลเล็กชันที่ว่างเปล่า คุณสามารถตรวจสอบว่าCompositeNodeมีโหนดย่อยใดๆโดยใช้คุณสมบัติHasChildNodes.

ตัวอย่างโค้ดต่อไปนี้แสดงวิธีการระบุโหนดย่อยทันทีของ CompositeNode โดยใช้ตัวระบุที่ให้มาโดยคอลเลกชัน ChildNodes:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
System::SharedPtr<Document> doc = System::MakeObject<Document>();
System::SharedPtr<Paragraph> paragraph = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 0, true));
System::SharedPtr<NodeCollection> children = paragraph->get_ChildNodes();
for (System::SharedPtr<Node> child : System::IterateOver(children))
{
if (System::ObjectExt::Equals(child->get_NodeType(), NodeType::Run))
{
// Say we found the node that we want, do something useful.
System::SharedPtr<Run> run = System::DynamicCast<Run>(child);
std::cout << run->get_Text().ToUtf8String() << std::endl;
}
}

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการระบุโหนดย่อยในทันทีของCompositeNodeโดยใช้การเข้าถึงการทำดัชนี:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
System::SharedPtr<Document> doc = System::MakeObject<Document>();
System::SharedPtr<Paragraph> paragraph = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 0, true));
System::SharedPtr<NodeCollection> children = paragraph->get_ChildNodes();
for (int32_t i = 0; i < children->get_Count(); i++)
{
System::SharedPtr<Node> child = children->idx_get(i);
// Paragraph may contain children of various types such as runs, shapes and so on.
if (System::ObjectExt::Equals(child->get_NodeType(), NodeType::Run))
{
// Say we found the node that we want, do something useful.
System::SharedPtr<Run> run = System::DynamicCast<Run>(child);
std::cout << run->get_Text().ToUtf8String() << std::endl;
}
}

โหนดพี่น้อง

คุณสามารถขอรับโหนดที่นำหน้าหรือติดตามโหนดเฉพาะโดยใช้คุณสมบัติPreviousSiblingและNextSiblingตามลำดับ ถ้าโหนดเป็นลูกคนสุดท้ายของพาเรนต์คุณสมบัติNextSiblingคือnull ในทางกลับกันถ้าโหนดเป็นลูกคนแรกของแม่คุณสมบัติPreviousSiblingคือnull.

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการเยี่ยมชมโหนดลูกโดยตรงและโดยอ้อมทั้งหมดของโหนดค:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
void TraverseAllNodes(System::SharedPtr<CompositeNode> parentNode)
{
// This is the most efficient way to loop through immediate children of a node.
for (System::SharedPtr<Node> childNode = parentNode->get_FirstChild(); childNode != nullptr; childNode = childNode->get_NextSibling())
{
// Do some useful work.
std::cout << Node::NodeTypeToString(childNode->get_NodeType()).ToUtf8String() << std::endl;
// Recurse into the node if it is a composite node.
if (childNode->get_IsComposite())
{
TraverseAllNodes(System::DynamicCast<CompositeNode>(childNode));
}
}
}
void RecurseAllNodes(System::String const &inputDataDir)
{
// Open a document.
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"Node.RecurseAllNodes.doc");
// Invoke the recursive function that will walk the tree.
TraverseAllNodes(doc);
}

การเข้าถึงที่พิมพ์ไปยังโหนดเด็กและแม่

จนถึงขณะนี้เราได้กล่าวถึงคุณสมบัติที่ส่งคืนหนึ่งในชนิดฐาน-NodeหรือCompositeNode แต่บางครั้งมีสถานการณ์ที่คุณอาจต้องโยนค่าไปยังคลาสโหนดที่เฉพาะเจาะจงเช่นRunหรือParagraph นั่นคือคุณไม่สามารถหนีจากการหล่อเมื่อทำงานกับAspose.WordsDOMซึ่งเป็นคอมโพสิต.

เพื่อลดความจำเป็นในการแคสต์คลาสAspose.Wordsส่วนใหญ่มีคุณสมบัติและคอลเล็กชันที่ให้การเข้าถึงที่ มีสามรูปแบบพื้นฐานของการเข้าถึงที่พิมพ์เป็น:

  • โหนดพาเรนต์แสดงคุณสมบัติที่พิมพ์FirstXXXและLastXXX ตัวอย่างเช่นDocumentมีFirstSectionและLastSectionคุณสมบัติ ในทำนองเดียวกันTableมีคุณสมบัติเช่นFirstRow,LastRowและอื่นๆ.
  • โหนดพาเรนต์แสดงคอลเล็กชันที่พิมพ์ของโหนดย่อยเช่นDocument.Sections,Body.Paragraphsและโหนดอื่นๆ.
  • โหนดย่อยให้สิทธิ์การเข้าถึงที่พิมพ์ไปยังพาเรนต์เช่นRun.ParentParagraph,Paragraph.ParentSectionและอื่นๆ.

มบัติทั่วไปที่สืบทอดมาจากNode.ParentNodeและCompositeNode.FirstChild.

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการใช้คุณสมบัติที่พิมพ์เพื่อเข้าถึงโหนดของแผนผังเอกสาร:

For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C
System::SharedPtr<Document> doc = System::MakeObject<Document>();
System::SharedPtr<Section> section = doc->get_FirstSection();
// Quick typed access to the Body child node of the Section.
System::SharedPtr<Body> body = section->get_Body();
// Quick typed access to all Table child nodes contained in the Body.
System::SharedPtr<TableCollection> tables = body->get_Tables();
for (System::SharedPtr<Table> table : System::IterateOver<System::SharedPtr<Table>>(tables))
{
// Quick typed access to the first row of the table.
if (table->get_FirstRow() != nullptr)
{
table->get_FirstRow()->Remove();
}
// Quick typed access to the last row of the table.
if (table->get_LastRow() != nullptr)
{
table->get_LastRow()->Remove();
}
}