Aspose.Words об'єктна модель документа (DOM)

Об’єктна модель документа Aspose.Words (DOM) являє собою представлення документа Word в пам’яті. Об’єктна модель документа Aspose.Words DOM дозволяє програмно зчитувати вміст і форматування документа Word, маніпулювати ними і змінювати їх.

У цьому розділі описуються основні класи Aspose.Words DOM та їх взаємозв’язки. Використовуючи класи Aspose.Words DOM, ви можете отримати програмний доступ до елементів документа та форматування.

Створити дерево об’єктів документа

Коли документ зчитується в Aspose.Words DOM, то будується дерево об’єктів, і різні типи елементів вихідного документа мають свої власні об’єкти дерева DOM з різними властивостями.

Побудова дерева вузлів документа

Коли Aspose.Words зчитує документ Word в пам’ять, він створює об’єкти різних типів, які представляють різні елементи документа. Кожен фрагмент тексту, абзац, таблиця або розділ є вузлом, і навіть сам документ є вузлом. 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, що представляють елементи документа Word.

Отримуємо Node Тип

Хоча класу Node достатньо, щоб відрізняти різні вузли один від одного, Aspose.Words надає перерахування NodeType для спрощення деяких задач API, таких як вибір вузлів певного типу.

Тип кожного вузла можна визначити за допомогою властивості NodeType. Ця властивість повертає значення перерахування NodeType. Наприклад, вузол абзацу, представлений класом Paragraph, повертає значення NodeType.Paragraph, а вузол таблиці, представлений класом Table, повертає значення NodeType.Table.

Наступний приклад показує, як отримати тип вузла за допомогою перерахування 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 потрібен об’єкт document, переданий конструктору.

При створенні нового абзацу за допомогою DocumentBuilder конструктор завжди має клас Document, пов’язаний з ним через властивість DocumentBuilder.Document.

У наступному прикладі коду показано, що при створенні будь-якого вузла завжди визначається документ, якому буде належати цей вузол:

Батьківський вузол

Кожен вузол має батьківський вузол, вказаний за допомогою властивості ParentNode. Вузол не має батьківського вузла, тобто значення ParentNode дорівнює null у наступних випадках:

  • Вузол щойно створений і ще не доданий до дерева.
  • Вузол був видалений з дерева.
  • Це кореневий вузол Document, який завжди має нульовий батьківський вузол.

Ви можете видалити вузол з батьківського, викликавши метод Remove.Наступний приклад коду показує, як отримати доступ до батьківського вузла:

Дочірні вузли

Найефективніший спосіб отримати доступ до дочірніх вузлів CompositeNode - це використання властивостей FirstChild та LastChild, які повертають перший та останній дочірні вузли відповідно. Якщо немає дочірніх вузлів, ці властивості повертають значення null.

CompositeNode

Якщо вузол не має дочірніх вузлів, то властивість ChildNodes повертає порожню колекцію. Ви можете перевірити, чи містить CompositeNode будь-які дочірні вузли, використовуючи властивість HasChildNodes.

Наступний приклад коду показує, як перерахувати безпосередні дочірні вузли CompositeNode, використовуючи перелічувач, наданий колекцією ChildNodes:

Наступний приклад коду показує, як перерахувати безпосередні дочірні вузли CompositeNode за допомогою індексованого доступу:

Споріднені вузли

Ви можете отримати вузол, який безпосередньо передує певному вузлу або слідує за ним, використовуючи властивості PreviousSibling та NextSibling відповідно. Якщо вузол є останнім дочірнім по відношенню до свого батьківського вузла, то властивість NextSibling дорівнює null. І навпаки, якщо вузол є першим дочірнім по відношенню до свого батьківського елементу, то властивість PreviousSibling дорівнює null.

Наступний приклад коду показує, як ефективно відвідувати всі прямі та непрямі дочірні вузли складеного вузла:

Типізований доступ до дочірніх і батьківських вузлів

До цього часу ми обговорювали властивості, які повертають один із базових типів – Node або CompositeNode. Але іноді виникають ситуації, коли може знадобитися привести значення до певного класу вузлів, наприклад Run або Paragraph. Тобто, ви не можете повністю відмовитися від приведення при роботі з Aspose.Words DOM, який є складовим.

Щоб зменшити потребу в приведенні у відповідність, більшість класів Aspose.Words надають властивості та колекції, які забезпечують суворо набраний доступ. Існує три основні шаблони типізованого доступу:

  • Батьківський вузол надає набрані властивості FirstXXX та LastXXX. Наприклад, у Document є властивості FirstSection і LastSection. Аналогічно, у Table є такі властивості, як FirstRow, LastRow та інші.
  • Батьківський вузол надає набрану колекцію дочірніх вузлів, таких як Document.Sections, Body.Paragraphs та інші.
  • Дочірній вузол надає набраний доступ до свого батьківського вузла, наприклад Run.ParentParagraph, Paragraph.ParentSection та інші.

Набрані властивості-це просто корисні ярлики, які іноді забезпечують легший доступ, ніж загальні властивості, успадковані від Node.ParentNode та CompositeNode.FirstChild.

Наступний приклад коду показує, як використовувати набрані властивості для доступу до вузлів дерева документів: