Aspose.Words Document Object Model (DOM)
Aspose.Words Document Object Model (DOM) は、Word ドキュメントのメモリ内表現です。 Aspose.Words DOM を使用すると、Word ドキュメントのコンテンツと書式設定をプログラムで読み取り、操作、変更できます。
このセクションでは、Aspose.Words DOM の主要なクラスとそれらの関係について説明します。 Aspose.Words DOM クラスを使用すると、ドキュメント要素と書式設定にプログラムからアクセスできます。
Document
オブジェクト ツリー {#create-a-document-objects-tree} の作成
ドキュメントが Aspose.Words DOM に読み込まれると、オブジェクト ツリーが構築され、ソース ドキュメントのさまざまなタイプの要素がさまざまなプロパティを持つ独自の DOM ツリー オブジェクトを持ちます。
ドキュメント ノード ツリーの構築
Aspose.Words が Word 文書をメモリに読み取ると、さまざまな文書要素を表すさまざまなタイプのオブジェクトが作成されます。テキスト、段落、表、セクションのすべてがノードであり、文書自体もノードです。 Aspose.Words は、ドキュメント ノード タイプごとにクラスを定義します。
Aspose.Words のドキュメント ツリーは、複合デザイン パターンに従います。
- すべてのノード クラスは、最終的には Aspose.Words Document Object Model の基本クラスである Node クラスから派生します。
- Section や Paragraph など、他のノードを含むことができるノードは CompositeNode クラスから派生し、CompositeNode クラスは Node クラスから派生します。
以下の図は、Aspose.Words Document Object Model (DOM) のノード クラス間の継承を示しています。抽象クラスの名前は斜体で表示されます。

例を見てみましょう。次の図は、さまざまなタイプのコンテンツを含む Microsoft Word ドキュメントを示しています。

上記のドキュメントを Aspose.Words DOM に読み込むと、以下のスキーマに示すようにオブジェクトのツリーが作成されます。

Document、Section、Paragraph、Table、Shape、Run、および図上のその他すべての省略記号は、Word ドキュメントの要素を表す Aspose.Words オブジェクトです。
Node
タイプ {#get-a-node-type} を取得する
Node クラスは異なるノードを相互に区別するのに十分ですが、Aspose.Words は特定のタイプのノードの選択など、一部の API タスクを簡素化する NodeType 列挙を提供します。
各ノードのタイプは、Node.node_type プロパティを使用して取得できます。このプロパティは、NodeType 列挙値を返します。たとえば、Paragraph クラスで表される段落ノードは NodeType.PARAGRAPH を返し、Table クラスで表される表ノードは NodeType.TABLE を返します。
次の例は、NodeType 列挙を使用してノード タイプを取得する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
type = doc.node_type |
ドキュメント ツリー ナビゲーション
Aspose.Words はドキュメントをノード ツリーとして表現し、ノード間を移動できるようにします。このセクションでは、Aspose.Words でドキュメント ツリーを探索および移動する方法について説明します。
前に示したサンプル ドキュメントをドキュメント エクスプローラーで開くと、ノード ツリーが Aspose.Words で表現されているとおりに表示されます。

ドキュメント ノードの関係
ツリー内のノード間には次のような関係があります。
- 別のノードを含むノードは parent.
- 親ノードに含まれるノードが child. である同じ親の子ノードは sibling ノードです。
- root ノードは常に Document ノードです。
他のノードを含むことができるノードは CompositeNode クラスから派生し、すべてのノードは最終的に Node クラスから派生します。これら 2 つの基本クラスは、ツリー構造のナビゲーションと変更のための共通のメソッドとプロパティを提供します。
次の UML オブジェクト図は、サンプル ドキュメントのいくつかのノードと、親、子、兄弟プロパティを介したそれらの相互関係を示しています。

ドキュメントはノード所有者です
スタイルやリストなどの重要なドキュメント全体の構造が Document ノードに格納されるため、ノードは常に特定のドキュメントに属します。これは、ノードが作成されたばかりか、ツリーから削除されたばかりであってもです。たとえば、各段落にはドキュメントに対してグローバルに定義されたスタイルが割り当てられているため、Document なしで Paragraph を作成することはできません。このルールは、新しいノードを作成するときに使用されます。新しい Paragraph を DOM に直接追加するには、ドキュメント オブジェクトをコンストラクターに渡す必要があります。
DocumentBuilder を使用して新しい段落を作成する場合、ビルダーには常に、DocumentBuilder.document プロパティを通じてそれにリンクされた Document クラスがあります。
次のコード例は、ノードを作成するときに、そのノードを所有するドキュメントが常に定義されることを示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
# Creating a new node of any type requires a document passed into the constructor. | |
para = aw.Paragraph(doc) | |
# The new paragraph node does not yet have a parent. | |
print(f"Paragraph has no parent node: {para.parent_node == None}") | |
# But the paragraph node knows its document. | |
print(f"Both nodes' documents are the same: {para.document == 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.paragraph_format.style_name = "Heading 1" | |
# Now add the paragraph to the main text of the first section. | |
doc.first_section.body.append_child(para) | |
# The paragraph node is now a child of the Body node. | |
print(f"Paragraph has a parent node: {para.parent_node != None}") |
親ノード
各ノードには、parent_node プロパティで指定された親があります。次の場合、ノードには親ノードがありません。つまり、parent_node は None です。
- ノードは作成されたばかりで、まだツリーに追加されていません。
- ノードがツリーから削除されました。
- これは、常に None の親ノードを持つルート Document ノードです。
Node.remove メソッドを呼び出すことで、親からノードを削除できます。次のコード例は、親ノードにアクセスする方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
# The section is the first child node of the document. | |
section = doc.first_child | |
# The section's parent node is the document. | |
print(f"Section parent is the document: {doc == section.parent_node}") |
子ノード
CompositeNode の子ノードにアクセスする最も効率的な方法は、最初と最後の子ノードをそれぞれ返す first_child プロパティと last_child プロパティを使用することです。子ノードがない場合、これらのプロパティは None を返します。
CompositeNode は、子ノードへのインデックス付きまたは列挙型のアクセスを可能にする get_child_nodes コレクションも提供します。 get_child_nodes メソッドは、ノードのライブ コレクションを返します。つまり、ノードが削除または追加されるなど、ドキュメントが変更されるたびに、get_child_nodes コレクションが自動的に更新されます。
ノードに子がない場合、get_child_nodes メソッドは空のコレクションを返します。 has_child_nodes プロパティを使用して、CompositeNode に子ノードが含まれているかどうかを確認できます。
次のコード例は、get_child_nodes コレクションによって提供される列挙子を使用して CompositeNode の直接の子ノードを列挙する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
paragraph = doc.get_child(aw.NodeType.PARAGRAPH, 0, True).as_paragraph() | |
children = paragraph.child_nodes | |
for child in children : | |
# A paragraph may contain children of various types such as runs, shapes, and others. | |
if child.node_type == aw.NodeType.RUN : | |
run = child.as_run() | |
print(run.text) | |
兄弟ノード
previous_sibling プロパティと next_sibling プロパティをそれぞれ使用して、特定のノードの直前または直後のノードを取得できます。ノードがその親の最後の子である場合、next_sibling プロパティは None です。逆に、ノードがその親の最初の子である場合、previous_sibling プロパティは None です。
次のコード例は、複合ノードのすべての直接および間接の子ノードに効率的にアクセスする方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
def test_recurse_all_nodes(self) : | |
doc = aw.Document(docs_base.my_dir + "Paragraphs.docx") | |
# Invoke the recursive function that will walk the tree. | |
self.traverse_all_nodes(doc) | |
# <summary> | |
# A simple function that will walk through all children of a specified node recursively | |
# and print the type of each node to the screen. | |
# </summary> | |
def traverse_all_nodes(self, parentNode) : | |
# This is the most efficient way to loop through immediate children of a node. | |
for childNode in parentNode.child_nodes : | |
print(aw.Node.node_type_to_string(childNode.node_type)) | |
# Recurse into the node if it is a composite node. | |
if childNode.is_composite : | |
self.traverse_all_nodes(childNode.as_composite_node()) | |
子ノードおよび親ノードへの型付きアクセス
これまで、基本タイプの 1 つである Node または CompositeNode を返すプロパティについて説明してきました。ただし、場合によっては、Run や Paragraph などの特定のノード クラスに値をキャストする必要がある場合があります。つまり、複合である Aspose.Words DOM を使用する場合、キャストから完全に逃れることはできません。
キャストの必要性を減らすために、ほとんどの Aspose.Words クラスは、厳密に型指定されたアクセスを提供するプロパティとコレクションを提供します。型付きアクセスには 3 つの基本パターンがあります。
- 親ノードは、型指定された first_XXX および last_XXX プロパティを公開します。たとえば、Document には first_section プロパティと last_section プロパティがあります。同様に、Table には first_row、last_row などのプロパティがあります。
- 親ノードは、Document.sections、Body.paragraphs などの子ノードの型付きコレクションを公開します。
- 子ノードは、Run.parent_paragraph、Paragraph.parent_section などの親ノードへの型付きアクセスを提供します。
型付きプロパティは単なる便利なショートカットであり、Node.parent_node や CompositeNode.first_child から継承された汎用プロパティよりも簡単にアクセスできる場合があります。
次のコード例は、型付きプロパティを使用してドキュメント ツリーのノードにアクセスする方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET | |
doc = aw.Document() | |
section = doc.first_section | |
body = section.body | |
# Quick typed access to all Table child nodes contained in the Body. | |
tables = body.tables | |
for table in tables : | |
# Quick typed access to the first row of the table. | |
if table.first_row != None : | |
table.first_row.remove() | |
# Quick typed access to the last row of the table. | |
if table.last_row != None : | |
table.last_row.remove() | |