Aspose.Words نموذج كائن المستند (DOM)

نموذج كائن المستند Aspose.Words (DOM) هو تمثيل في الذاكرة لمستند ورد. و Aspose.Words DOM يسمح لك لقراءة برمجيا، والتلاعب، وتعديل المحتوى والتنسيق من وثيقة ورد.

يصف هذا القسم الفئات الرئيسية لـ Aspose.Words DOM وعلاقاتهم. باستخدام فئات Aspose.Words DOM، يمكنك الحصول على وصول برمجي إلى عناصر المستند والتنسيق.

إنشاء شجرة كائن المستند

عند قراءة مستند في Aspose.Words DOM، يتم إنشاء شجرة كائن وأنواع مختلفة من عناصر المستند المصدر لها كائنات شجرة DOM الخاصة بها بخصائص مختلفة.

بناء شجرة العقد وثيقة

عندما يقرأ 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.Words DOM، يتم إنشاء شجرة الكائنات، كما هو موضح في المخطط أدناه.

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.Words DOM، وهو مركب.

لتقليل الحاجة إلى الإرسال، توفر معظم فئات Aspose.Words خصائص ومجموعات توفر وصولا مكتوبا بشدة. هناك ثلاثة أنماط أساسية للوصول المكتوب:

الخصائص المكتوبة هي مجرد اختصارات مفيدة توفر أحيانا وصولا أسهل من الخصائص العامة الموروثة من 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();
}
}