Aspose.Words Model Obiect Document (DOM)

Modelul de obiect Document Aspose.Words (DOM) este o reprezentare în memorie a unui document Word. Aspose.Words DOM vă permite să citiți, să manipulați și să modificați în mod programatic conținutul și formatarea unui document Word.

Această secțiune descrie clasele principale ale Aspose.Words DOM și relațiile lor. Folosind clasele Aspose.Words DOM, puteți obține acces programatic la elementele documentului și formatare.

Creare Document Arbore Obiect

Când un document este citit în Aspose.Words DOM, atunci este construit un arbore de obiecte și diferite tipuri de elemente ale documentului sursă au propriile lor obiecte de copac DOM cu proprietăți diferite.

Construiți Arborele Nodurilor Documentului

Când Aspose.Words citește un document Word în memorie, acesta creează obiecte de diferite tipuri care reprezintă diferite elemente ale documentului. Fiecare rulare a unui text, paragraf, tabel sau secțiune este un nod și chiar documentul în sine este un nod. Aspose.Words definește o clasă pentru fiecare tip de nod de document.

Arborele de documente din Aspose.Words urmează modelul de proiectare compozit:

  • Toate clasele de noduri derivă în cele din urmă din clasa Node, care este clasa de bază din modelul obiectului Document Aspose.Words.
  • Nodurile care pot conține alte noduri, de exemplu, Section sau Paragraph, derivă din clasa CompositeNode, care la rândul său derivă din clasa Node.

Diagrama furnizată mai jos arată moștenirea între clasele de noduri ale modelului de obiect Document Aspose.Words (DOM). Numele claselor abstracte sunt în italice.

aspose-words-dom-aspose-words-cpp

Să ne uităm la un exemplu. Următoarea imagine prezintă un document Microsoft Word cu diferite tipuri de conținut.

document-example-aspose-words-cpp

Când citiți documentul de mai sus în Aspose.Words DOM, arborele obiectelor este creat, așa cum se arată în schema de mai jos.

document-example-dom-aspose-words-cpp

Document, Section, Paragraph, Table, Shape, Run, și toate celelalte elipse din diagramă sunt obiecte Aspose.Words care reprezintă elemente ale documentului Word.

Obțineți un Node Tip

Deși clasa Node este suficientă pentru a distinge diferite noduri unele de altele, Aspose.Words oferă enumerarea NodeType pentru a simplifica unele sarcini API, cum ar fi selectarea nodurilor de un anumit tip.

Tipul fiecărui nod poate fi obținut folosind proprietatea NodeType. Această proprietate returnează o valoare de enumerare NodeType. De exemplu, un nod de paragraf reprezentat de clasa Paragraph returnează NodeType.Paragraph, iar un nod de tabel reprezentat de clasa Table returnează NodeType.Table.

Următorul exemplu arată cum să obțineți un tip de nod folosind enumerarea 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();

Document Tree Navigation

Aspose.Words reprezintă un document ca arbore de noduri, care vă permite să navigați între noduri. Această secțiune descrie modul de explorare și navigare a arborelui de documente în Aspose.Words.

Când deschideți documentul eșantion, prezentat anterior, în Document Explorer, arborele nodului apare exact așa cum este reprezentat în Aspose.Words.

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

Relații Nod Document

Nodurile din copac au relații între ele:

  • Un nod care conține un alt nod este un parent.
  • Nodul conținut în nodul părinte este un child. nodurile copil ale aceluiași părinte sunt sibling noduri.
  • Nodul root este întotdeauna nodul Document.

Nodurile care pot conține alte noduri derivă din clasa CompositeNode, iar toate nodurile derivă în cele din urmă din clasa Node. Aceste două clase de bază oferă metode și proprietăți comune pentru navigarea și modificarea structurii arborești.

Următoarea diagramă de obiecte UML prezintă mai multe noduri ale documentului eșantion și relațiile lor între ele prin proprietățile părinte, copil și frate:

document-nodes-relationships-aspose-words-cpp

Documentul este proprietarul nodului

Un nod aparține întotdeauna unui anumit document, chiar dacă tocmai a fost creat sau eliminat din copac, deoarece structurile vitale la nivelul întregului document, cum ar fi stilurile și listele, sunt stocate în nodul Document. De exemplu, nu este posibil să aveți un Paragraph fără un Document deoarece fiecare paragraf are un stil atribuit care este definit global pentru document. Această regulă este utilizată la crearea oricăror noduri noi. Adăugarea unui nou Paragraph Direct la DOM necesită un obiect document transmis constructorului.

Când creați un paragraf nou folosind DocumentBuilder, constructorul are întotdeauna o clasă Document legată de acesta prin proprietatea DocumentBuilder.Document.

Următorul exemplu de cod arată că atunci când creați orice nod, un document care va deține nodul este întotdeauna definit:

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;

Nodul Părinte

Fiecare nod are un părinte specificat de proprietatea ParentNode. Un nod nu are nod părinte, adică ParentNode este nul, în următoarele cazuri:

  • Nodul tocmai a fost creat și nu a fost încă adăugat la copac.
  • Nodul a fost scos din copac.
  • Acesta este nodul rădăcină Document care are întotdeauna un nod părinte nul.

Puteți elimina un nod din părintele său apelând metoda Remove.Următorul exemplu de cod arată cum să accesați nodul părinte:

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;

Noduri Copil

Cel mai eficient mod de a accesa nodurile copil ale unui CompositeNode este prin proprietățile FirstChild și LastChild care returnează primul și ultimul nod copil, respectiv. Dacă nu există noduri copil, aceste proprietăți returnează null.

CompositeNode

Dacă un nod nu are copil, atunci proprietatea ChildNodes returnează o colecție goală. Puteți verifica dacă CompositeNode conține noduri copil folosind proprietatea HasChildNodes.

Următorul exemplu de cod arată cum să enumerați nodurile copil imediate ale unui CompositeNode folosind enumeratorul furnizat de colecția 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;
}
}

Următorul exemplu de cod arată cum să enumerați nodurile copil imediate ale unui CompositeNode folosind accesul indexat:

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;
}
}

Noduri De Frate

Puteți obține nodul care precede sau urmează imediat un anumit nod folosind proprietățile PreviousSibling și, respectiv, NextSibling. Dacă un nod este ultimul copil al părintelui său, atunci proprietatea NextSibling este null. În schimb, dacă nodul este primul copil al părintelui său, proprietatea PreviousSibling este null.

Următorul exemplu de cod arată cum să vizitați eficient toate nodurile copil directe și indirecte ale unui nod compus:

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);
}

Acces tastat la nodurile copil și părinte

Până în prezent, am discutat despre proprietățile care returnează unul dintre tipurile de bază – Node sau CompositeNode. Dar uneori există situații în care ar putea fi necesar să aruncați valori într-o anumită clasă de noduri, cum ar fi Run sau Paragraph. Adică, nu puteți scăpa complet de turnare atunci când lucrați cu Aspose.Words DOM, care este compozit.

Pentru a reduce nevoia de turnare, majoritatea claselor Aspose.Words oferă proprietăți și colecții care oferă acces puternic tipărit. Există trei modele de bază de acces tastat:

Proprietățile tastate sunt doar scurtături utile care uneori oferă acces mai ușor decât proprietățile generice moștenite de la Node.ParentNode și CompositeNode.FirstChild.

Următorul exemplu de cod arată cum să utilizați proprietățile tastate pentru a accesa nodurile arborelui de documente:

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();
}
}