Aspose.Words Document Object Model (DOM)
Das Aspose.Words Document Object Model (DOM) ist eine speicherinterne Darstellung eines Word-Dokuments. Mit Aspose.Words DOM können Sie den Inhalt und die Formatierung eines Word-Dokuments programmgesteuert lesen, bearbeiten und ändern.
In diesem Abschnitt werden die Hauptklassen von Aspose.Words DOM und ihre Beziehungen beschrieben. Durch die Verwendung der Aspose.Words-DOM-Klassen können Sie programmgesteuerten Zugriff auf Dokumentelemente und Formatierungen erhalten.
Erstellen Sie einen Document
-Objektbaum
Wenn ein Dokument in Aspose.Words DOM eingelesen wird, wird ein Objektbaum erstellt und verschiedene Arten von Elementen des Quelldokuments verfügen über eigene DOM-Baumobjekte mit verschiedenen Eigenschaften.
Dokumentknotenbaum {#build-document-nodes-tree} erstellen
Wenn Aspose.Words ein Word-Dokument in den Speicher einliest, erstellt es Objekte unterschiedlichen Typs, die verschiedene Dokumentelemente darstellen. Jeder Textabschnitt, jeder Absatz, jede Tabelle oder jeder Abschnitt ist ein Knoten, und sogar das Dokument selbst ist ein Knoten. Aspose.Words definiert eine Klasse für jeden Dokumentknotentyp.
Der Dokumentenbaum in Aspose.Words folgt dem Composite Design Pattern:
– Alle Knotenklassen leiten sich letztlich von der Node-Klasse ab, die die Basisklasse im Aspose.Words-Document Object Model darstellt.
- Knoten, die andere Knoten enthalten können, beispielsweise Section oder Paragraph, werden von der CompositeNode-Klasse abgeleitet, die wiederum von der Node-Klasse abgeleitet ist.
Das unten bereitgestellte Diagramm zeigt die Vererbung zwischen Knotenklassen des Aspose.Words Document Object Model (DOM). Die Namen abstrakter Klassen sind kursiv geschrieben.
Schauen wir uns ein Beispiel an. Das folgende Bild zeigt ein Microsoft Word-Dokument mit verschiedenen Inhaltstypen.
Beim Einlesen des obigen Dokuments in Aspose.Words DOM wird der Objektbaum erstellt, wie im folgenden Schema dargestellt.
Document, Section, Paragraph, Table, Shape, Run und alle anderen Ellipsen im Diagramm sind Aspose.Words-Objekte, die Elemente des Word-Dokuments darstellen.
Holen Sie sich ein Node
-Typ-
Obwohl die Node-Klasse ausreicht, um verschiedene Knoten voneinander zu unterscheiden, stellt Aspose.Words die NodeType-Enumeration bereit, um einige API-Aufgaben zu vereinfachen, beispielsweise die Auswahl von Knoten eines bestimmten Typs.
Der Typ jedes Knotens kann mithilfe der Node.node_type-Eigenschaft ermittelt werden. Diese Eigenschaft gibt einen NodeType-Enumerationswert zurück. Beispielsweise gibt ein durch die Paragraph-Klasse dargestellter Absatzknoten NodeType.PARAGRAPH zurück und ein durch die Table-Klasse dargestellter Tabellenknoten gibt NodeType.TABLE zurück.
Das folgende Beispiel zeigt, wie man mithilfe der NodeType-Enumeration einen Knotentyp erhält:
Dokumentenbaumnavigation
Aspose.Words stellt ein Dokument als Knotenbaum dar, der Ihnen die Navigation zwischen Knoten ermöglicht. In diesem Abschnitt wird beschrieben, wie Sie den Dokumentbaum in Aspose.Words erkunden und darin navigieren.
Wenn Sie das zuvor vorgestellte Beispieldokument im Dokumenten-Explorer öffnen, wird der Knotenbaum genau so angezeigt, wie er in Aspose.Words dargestellt wird.
Dokumentknotenbeziehungen
Die Knoten im Baum haben Beziehungen zwischen ihnen:
- Ein Knoten, der einen anderen Knoten enthält, ist ein parent.
- Der im übergeordneten Knoten enthaltene Knoten ist ein child.. Untergeordnete Knoten desselben übergeordneten Knotens sind sibling-Knoten.
- Der root-Knoten ist immer der Document-Knoten.
Die Knoten, die andere Knoten enthalten können, leiten sich von der CompositeNode-Klasse ab, und alle Knoten leiten sich letztendlich von der Node-Klasse ab. Diese beiden Basisklassen stellen gemeinsame Methoden und Eigenschaften für die Navigation und Änderung der Baumstruktur bereit.
Das folgende UML-Objektdiagramm zeigt mehrere Knoten des Beispieldokuments und ihre Beziehungen zueinander über die Eigenschaften “Eltern”, “Kind” und “Geschwister”:
Das Dokument ist Knoteneigentümer
Ein Knoten gehört immer zu einem bestimmten Dokument, auch wenn er gerade erst erstellt oder aus dem Baum entfernt wurde, da wichtige dokumentweite Strukturen wie Stile und Listen im Document-Knoten gespeichert sind. Beispielsweise ist ein Paragraph ohne Document nicht möglich, da jedem Absatz ein Stil zugewiesen ist, der global für das Dokument definiert ist. Diese Regel wird beim Erstellen neuer Knoten verwendet. Das direkte Hinzufügen eines neuen Paragraph zum DOM erfordert die Übergabe eines Dokumentobjekts an den Konstruktor.
Beim Erstellen eines neuen Absatzes mit DocumentBuilder verfügt der Builder immer über eine damit verknüpfte Document-Klasse über die DocumentBuilder.document-Eigenschaft.
Das folgende Codebeispiel zeigt, dass beim Erstellen eines Knotens immer ein Dokument definiert wird, das Eigentümer des Knotens sein wird:
Elternknoten
Jeder Knoten hat einen übergeordneten Knoten, der durch die parent_node-Eigenschaft angegeben wird. Ein Knoten hat in den folgenden Fällen keinen übergeordneten Knoten, d. h. parent_node ist None:
- Der Knoten wurde gerade erstellt und noch nicht zum Baum hinzugefügt.
- Der Knoten wurde aus dem Baum entfernt. – Dies ist der Root-Document-Knoten, der immer einen None-Elternknoten hat.
Sie können einen Knoten von seinem übergeordneten Knoten entfernen, indem Sie die Node.remove-Methode aufrufen. Das folgende Codebeispiel zeigt, wie auf den übergeordneten Knoten zugegriffen wird:
Untergeordnete Knoten
Der effizienteste Weg, auf untergeordnete Knoten einer CompositeNode zuzugreifen, ist über die first_child- und last_child-Eigenschaften, die jeweils den ersten und letzten untergeordneten Knoten zurückgeben. Wenn keine untergeordneten Knoten vorhanden sind, geben diese Eigenschaften None zurück.
CompositeNode stellt außerdem die get_child_nodes-Sammlung bereit, die den indizierten oder nummerierten Zugriff auf die untergeordneten Knoten ermöglicht. Die get_child_nodes-Methode gibt eine Live-Sammlung von Knoten zurück, was bedeutet, dass die get_child_nodes-Sammlung automatisch aktualisiert wird, wenn das Dokument geändert wird, beispielsweise wenn Knoten entfernt oder hinzugefügt werden.
Wenn ein Knoten kein untergeordnetes Element hat, gibt die get_child_nodes-Methode eine leere Sammlung zurück. Mithilfe der has_child_nodes-Eigenschaft können Sie überprüfen, ob der CompositeNode untergeordnete Knoten enthält.
Das folgende Codebeispiel zeigt, wie unmittelbar untergeordnete Knoten eines CompositeNode mithilfe des von der get_child_nodes-Sammlung bereitgestellten Enumerators aufgezählt werden:
Geschwisterknoten
Mithilfe der previous_sibling- bzw. next_sibling-Eigenschaften können Sie den Knoten ermitteln, der einem bestimmten Knoten unmittelbar vorangeht oder folgt. Wenn ein Knoten das letzte untergeordnete Element seines übergeordneten Knotens ist, ist die next_sibling-Eigenschaft None. Wenn der Knoten umgekehrt das erste untergeordnete Element seines übergeordneten Knotens ist, ist die previous_sibling-Eigenschaft None.
Das folgende Codebeispiel zeigt, wie alle direkten und indirekten untergeordneten Knoten eines zusammengesetzten Knotens effizient besucht werden:
Typisierter Zugriff auf untergeordnete und übergeordnete Knoten
Bisher haben wir die Eigenschaften besprochen, die einen der Basistypen zurückgeben – Node oder CompositeNode. Aber manchmal gibt es Situationen, in denen Sie Werte in eine bestimmte Knotenklasse wie Run oder Paragraph umwandeln müssen. Das heißt, Sie können beim Arbeiten mit Aspose.Words DOM, das zusammengesetzt ist, nicht ganz auf das Casting verzichten.
Um den Bedarf an Umwandlungen zu reduzieren, stellen die meisten Aspose.Words-Klassen Eigenschaften und Sammlungen bereit, die einen stark typisierten Zugriff ermöglichen. Es gibt drei grundlegende Muster für den typisierten Zugriff:
– Ein übergeordneter Knoten stellt typisierte first_XXX- und last_XXX-Eigenschaften bereit. Beispielsweise verfügt das Document über first_section- und last_section-Eigenschaften. Ebenso verfügt Table über Eigenschaften wie first_row, last_row und andere. – Ein übergeordneter Knoten stellt eine typisierte Sammlung untergeordneter Knoten bereit, z. B. Document.sections, Body.paragraphs und andere. – Ein untergeordneter Knoten bietet typisierten Zugriff auf seinen übergeordneten Knoten, z. B. Run.parent_paragraph, Paragraph.parent_section und andere.
Typisierte Eigenschaften sind lediglich nützliche Verknüpfungen, die manchmal einen einfacheren Zugriff ermöglichen als generische Eigenschaften, die von Node.parent_node und CompositeNode.first_child übernommen wurden.
Das folgende Codebeispiel zeigt, wie typisierte Eigenschaften verwendet werden, um auf Knoten der Dokumentstruktur zuzugreifen: