Aspose.Words Modello oggetto documento (DOM)
Il Aspose.Words Document Object Model (DOM) è una rappresentazione in memoria di un documento Word. Aspose.Words DOM consente di leggere, manipolare e modificare a livello di programmazione il contenuto e la formattazione di un documento Word.
Questa sezione descrive le classi principali di Aspose.Words DOM e le loro relazioni. Utilizzando le classi Aspose.Words DOM, è possibile ottenere l’accesso programmatico agli elementi del documento e alla formattazione.
Crea Albero oggetti documento
Quando un documento viene letto in Aspose.Words DOM, viene creato un albero di oggetti e diversi tipi di elementi del documento di origine hanno i propri oggetti ad albero DOM con varie proprietà.
Struttura dei nodi del documento
Quando Aspose.Words legge un documento Word in memoria, crea oggetti di diversi tipi che rappresentano vari elementi del documento. Ogni esecuzione di un testo, paragrafo, tabella o sezione è un nodo e anche il documento stesso è un nodo. Aspose.Words definisce una classe per ogni tipo di nodo documento.
L’albero del documento in Aspose.Words segue il modello di progettazione composito:
- Tutte le classi di nodi derivano in ultima analisi dalla classe Node, che è la classe base nel modello a oggetti del documento Aspose.Words.
- I nodi che possono contenere altri nodi, ad esempio Section o Paragraph, derivano dalla classe CompositeNode, che a sua volta deriva dalla classe Node.
Il diagramma fornito di seguito mostra l’ereditarietà tra le classi di nodi del modello a oggetti del documento Aspose.Words (DOM). I nomi delle classi astratte sono in corsivo.

Node
.
Diamo un’occhiata a un esempio. L’immagine seguente mostra un documento Microsoft Word con diversi tipi di contenuto.

Quando si legge il documento sopra nel Aspose.Words DOM, viene creato l’albero degli oggetti, come mostrato nello schema seguente.

Document, Section, Paragraph, Table, Shape, Run, e tutte le altre ellissi sul diagramma sono oggetti Aspose.Words che rappresentano elementi del documento Word.
Ottieni unNode
Tipo
Sebbene la classe Node sia sufficiente per distinguere nodi diversi l’uno dall’altro, Aspose.Words fornisce l’enumerazione NodeType per semplificare alcune attività API, come la selezione di nodi di un tipo specifico.
Il tipo di ciascun nodo può essere ottenuto utilizzando la proprietà NodeType. Questa proprietà restituisce un valore di enumerazione NodeType. Ad esempio, un nodo paragrafo rappresentato dalla classe Paragraph restituisce NodeType.Paragraph e un nodo tabella rappresentato dalla classe Table restituisce NodeType.Table.
L’esempio seguente mostra come ottenere un tipo di nodo utilizzando l’enumerazione NodeType:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
// Returns NodeType.Document | |
int type = doc.getNodeType(); |
Navigazione Albero documenti
Aspose.Words rappresenta un documento come albero dei nodi, che consente di spostarsi tra i nodi. Questa sezione descrive come esplorare e navigare nell’albero dei documenti in Aspose.Words.
Quando si apre il documento di esempio, presentato in precedenza, in Esplora documenti, l’albero dei nodi appare esattamente come è rappresentato in Aspose.Words.

Relazioni nodo documento
I nodi nell’albero hanno relazioni tra di loro:
- Un nodo contenente un altro nodo è parent.
- Il nodo contenuto nel nodo padre è un child. Nodi figlio dello stesso genitore sono sibling nodi.
- Il nodo root è sempre il nodo Document.
I nodi che possono contenere altri nodi derivano dalla classe CompositeNode e tutti i nodi alla fine derivano dalla classe Node. Queste due classi base forniscono metodi e proprietà comuni per la navigazione e la modifica della struttura ad albero.
Il seguente diagramma oggetto UML mostra diversi nodi del documento di esempio e le loro relazioni tra loro tramite le proprietà padre, figlio e fratello:

Il documento è proprietario del nodo
Un nodo appartiene sempre a un particolare documento, anche se è stato appena creato o rimosso dall’albero, perché strutture vitali a livello di documento come stili ed elenchi sono memorizzate nel nodo Document. Ad esempio, non è possibile avere un Paragraph senza un Document perché ogni paragrafo ha uno stile assegnato definito globalmente per il documento. Questa regola viene utilizzata quando si creano nuovi nodi. L’aggiunta di un nuovo Paragraph direttamente al DOM richiede un oggetto documento passato al costruttore.
Quando si crea un nuovo paragrafo usando DocumentBuilder, il builder ha sempre una classe Document collegata ad esso tramite la proprietà DocumentBuilder.Document.
L’esempio di codice seguente mostra che quando si crea un nodo, viene sempre definito un documento che possederà il nodo:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// Open a file from disk. | |
Document doc = new Document(); | |
// Creating a new node of any type requires a document passed into the constructor. | |
Paragraph para = new Paragraph(doc); | |
// The new paragraph node does not yet have a parent. | |
System.out.println("Paragraph has no parent node: " + (para.getParentNode() == null)); | |
// But the paragraph node knows its document. | |
System.out.println("Both nodes' documents are the same: " + (para.getDocument() == doc)); | |
// 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.getParagraphFormat().setStyleName("Heading 1"); | |
// Now add the paragraph to the main text of the first section. | |
doc.getFirstSection().getBody().appendChild(para); | |
// The paragraph node is now a child of the Body node. | |
System.out.println("Paragraph has a parent node: " + (para.getParentNode() != null)); |
Nodo padre
Ogni nodo ha un genitore specificato dalla proprietà ParentNode. Un nodo non ha un nodo padre, cioè ParentNode è nullo, nei seguenti casi:
- Il nodo è stato appena creato e non è ancora stato aggiunto all’albero.
- Il nodo è stato rimosso dall’albero.
- Questo è il nodo root Document che ha sempre un nodo padre nullo.
È possibile rimuovere un nodo dal suo genitore chiamando il metodo Remove.Il seguente esempio di codice mostra come accedere al nodo padre:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// Create a new empty document. It has one section. | |
Document doc = new Document(); | |
// The section is the first child node of the document. | |
Node section = doc.getFirstChild(); | |
// The section's parent node is the document. | |
System.out.println("Section parent is the document: " + (doc == section.getParentNode())); |
Nodi figlio
Il modo più efficiente per accedere ai nodi figlio di un CompositeNode è tramite le proprietà FirstChild e LastChild che restituiscono rispettivamente il primo e l’ultimo nodo figlio. Se non ci sono nodi figlio, queste proprietà restituiscono null.
CompositeNode
Se un nodo non ha figli, la proprietà ChildNodes restituisce una raccolta vuota. È possibile verificare se CompositeNode contiene nodi figlio utilizzando la proprietà HasChildNodes.
L’esempio di codice seguente mostra come enumerare i nodi figlio immediati di un CompositeNode
utilizzando l’enumeratore fornito dalla raccolta ChildNodes
:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(dataDir + "Document.doc"); | |
Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); | |
NodeCollection children = paragraph.getChildNodes(); | |
for (Node child : (Iterable<Node>) children) { | |
// Paragraph may contain children of various types such as runs, shapes and so on. | |
if (child.getNodeType() == NodeType.RUN) { | |
// Say we found the node that we want, do something useful. | |
Run run = (Run) child; | |
System.out.println(run.getText()); | |
} | |
} |
L’esempio di codice seguente mostra come enumerare i nodi figlio immediati di un CompositeNode
utilizzando l’accesso indicizzato:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(dataDir + "Document.doc"); | |
Paragraph paragraph = (Paragraph) doc.getChild(NodeType.PARAGRAPH, 0, true); | |
NodeCollection children = paragraph.getChildNodes(); | |
for (int i = 0; i < children.getCount(); i++) { | |
Node child = children.get(i); | |
// Paragraph may contain children of various types such as runs, shapes and so on. | |
if (child.getNodeType() == NodeType.RUN) { | |
// Say we found the node that we want, do something useful. | |
Run run = (Run) child; | |
System.out.println(run.getText()); | |
} | |
} |
Nodi fratelli
È possibile ottenere il nodo che precede o segue immediatamente un particolare nodo utilizzando rispettivamente le proprietà PreviousSibling e NextSibling. Se un nodo è l’ultimo figlio del suo genitore, allora la proprietà NextSibling è null. Al contrario, se il nodo è il primo figlio del suo genitore, la proprietà PreviousSibling è null.
Il seguente esempio di codice mostra come visitare in modo efficiente tutti i nodi figlio diretti e indiretti di un nodo composito:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
public static void main(String[] args) throws Exception { | |
String dataDir = Utils.getSharedDataDir(ChildNodes.class) + "DocumentObjectModel/"; | |
recurseAllNodes(dataDir); | |
} | |
public static void recurseAllNodes(String dataDir) throws Exception { | |
// Open a document | |
Document doc = new Document(dataDir + "Node.RecurseAllNodes.doc"); | |
// Invoke the recursive function that will walk the tree. | |
traverseAllNodes(doc); | |
} | |
/** | |
* A simple function that will walk through all children of a specified node | |
* recursively and print the type of each node to the screen. | |
*/ | |
public static void traverseAllNodes(CompositeNode parentNode) throws Exception { | |
// This is the most efficient way to loop through immediate children of a node. | |
for (Node childNode = parentNode.getFirstChild(); childNode != null; childNode = childNode.getNextSibling()) { | |
// Do some useful work. | |
System.out.println(Node.nodeTypeToString(childNode.getNodeType())); | |
// Recurse into the node if it is a composite node. | |
if (childNode.isComposite()) | |
traverseAllNodes((CompositeNode) childNode); | |
} | |
} |
Accesso digitato ai nodi figlio e padre
Finora, abbiamo discusso le proprietà che restituiscono uno dei tipi di base - Node o CompositeNode. Ma a volte ci sono situazioni in cui potrebbe essere necessario trasmettere valori a una specifica classe di nodi, ad esempio Run o Paragraph. Cioè, non è possibile allontanarsi completamente dal casting quando si lavora con Aspose.Words DOM, che è composito.
Per ridurre la necessità di eseguire il casting, la maggior parte delle classi Aspose.Words fornisce proprietà e raccolte che forniscono un accesso fortemente tipizzato. Ci sono tre modelli di base di accesso digitato:
- Un nodo padre espone le proprietà FirstXXX e LastXXX digitate. Ad esempio, Document ha proprietà FirstSection e LastSection. Allo stesso modo, Table ha proprietà come FirstRow, LastRow e altre.
- Un nodo padre espone una raccolta tipizzata di nodi figlio, ad esempio Document.Sections, Body.Paragraphs e altri.
- Un nodo figlio fornisce l’accesso digitato al suo genitore, ad esempio Run.ParentParagraph, Paragraph.ParentSection e altri.
Le proprietà digitate sono semplicemente scorciatoie utili che a volte forniscono un accesso più semplice rispetto alle proprietà generiche ereditate da Node.ParentNode e CompositeNode.FirstChild.
L’esempio di codice seguente mostra come utilizzare le proprietà tipizzate per accedere ai nodi della struttura del documento:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
// Quick typed access to the first child Section node of the Document. | |
Section section = doc.getFirstSection(); | |
// Quick typed access to the Body child node of the Section. | |
Body body = section.getBody(); | |
// Quick typed access to all Table child nodes contained in the Body. | |
TableCollection tables = body.getTables(); | |
for (Table table : tables) { | |
// Quick typed access to the first row of the table. | |
if (table.getFirstRow() != null) | |
table.getFirstRow().remove(); | |
// Quick typed access to the last row of the table. | |
if (table.getLastRow() != null) | |
table.getLastRow().remove(); | |
} |