ドキュメント内のノード間のコンテンツの抽出
ドキュメントを操作する場合、ドキュメント内の特定の範囲からコンテンツを簡単に抽出できることが重要です。ただし、コンテンツは段落、表、画像などの複雑な要素で構成される場合があります。
どのようなコンテンツを抽出する必要があるかに関係なく、そのコンテンツを抽出する方法は常に、コンテンツを抽出するためにどのノードが選択されるかによって決まります。これらは、テキスト本文全体または単純なテキストの続きです。
多くの状況が考えられるため、コンテンツを抽出する際にはさまざまなノード タイプを考慮する必要があります。たとえば、次の間のコンテンツを抽出したい場合があります。
- 2 つの特定の段落
- 特定のテキストの続き
- 差し込みフィールドなどのさまざまなタイプのフィールド
- ブックマークまたはコメントの開始範囲と終了範囲
- さまざまなテキスト本文が別のセクションに含まれています
状況によっては、段落とフィールドの間、またはランとブックマークの間でコンテンツを抽出するなど、異なるノード タイプを組み合わせる必要がある場合もあります。
この記事では、異なるノード間でテキストを抽出するためのコード実装と、一般的なシナリオの例を示します。
コンテンツを抽出する理由
多くの場合、コンテンツを抽出する目的は、コンテンツを複製するか、新しいドキュメントに個別に保存することです。たとえば、コンテンツを抽出して次のことを行うことができます。
- 別のドキュメントにコピーします
- 文書の特定の部分を PDF または画像に変換
- 文書内の内容を何度も複製する
- 文書の残りの部分とは別に抽出されたコンテンツを操作します
これは、Aspose.Words と以下のコード実装を使用して簡単に実現できます。
コンテンツ抽出アルゴリズム
このセクションのコードは、一般化された再利用可能な 1 つのメソッドを使用して、上で説明したすべての考えられる状況に対処します。この手法の概要には次のものが含まれます。
- ドキュメントから抽出されるコンテンツの領域を決定するノードを収集します。これらのノードの取得は、抽出したい内容に基づいてユーザーのコード内で処理されます。
- これらのノードを以下に示す ExtractContent メソッドに渡します。また、マーカーとして機能するこれらのノードを抽出に含めるかどうかを示すブール値パラメーターも渡す必要があります。
- 抽出するように指定されたクローンコンテンツ (コピーされたノード) のリストを取得します。このノードのリストは、選択したコンテンツのみを含む新しいドキュメントを作成するなど、適切な方法で使用できます。
コンテンツを抽出する方法
ドキュメントからコンテンツを抽出するには、以下の コンテンツの抽出 メソッドを呼び出し、適切なパラメータを渡す必要があります。この方法の基礎となるのは、ブロック レベルのノード (段落とテーブル) を検索し、それらを複製して同一のコピーを作成することです。渡されたマーカー ノードがブロック レベルの場合、メソッドはそのレベルのコンテンツを単純にコピーして配列に追加できます。
ただし、マーカー ノードがインライン (段落の子) である場合、実行やブックマーク フィールドなどの段落をインライン ノードで分割する必要があるため、状況はより複雑になります。クローン化された親ノードのコンテンツはそうではありません。マーカー間に存在するものが削除されます。このプロセスは、インライン ノードが親段落の書式設定を確実に保持するために使用されます。このメソッドは、パラメーターとして渡されたノードのチェックも実行し、いずれかのノードが無効な場合は例外をスローします。このメソッドに渡されるパラメータは次のとおりです。
1.スタートノードとエンドノード。最初の 2 つのパラメータは、コンテンツの抽出をそれぞれ開始および終了する場所を定義するノードです。これらのノードは、ブロック レベル (Paragraph、Table、またはインライン レベル (Run、FieldStart、BookmarkStart など)) の両方にすることができます。
- フィールドを渡すには、対応する FieldStart オブジェクトを渡す必要があります。
- ブックマークを渡すには、BookmarkStart ノードと BookmarkEnd ノードを渡す必要があります。
- コメントを渡すには、CommentRangeStart ノードと CommentRangeEnd ノードを使用する必要があります。 1.包括的です。マーカーが抽出に含まれるかどうかを定義します。このオプションが false に設定され、同じノードまたは連続したノードが渡された場合、空のリストが返されます。
- FieldStart ノードが渡された場合、このオプションはフィールド全体を含めるか除外するかを定義します。
- BookmarkStart または BookmarkEnd ノードが渡された場合、このオプションはブックマークが含まれるか、それともブックマーク範囲間のコンテンツのみが含まれるかを定義します。
- CommentRangeStart または CommentRangeEnd ノードが渡された場合、このオプションはコメント自体を含めるか、コメント範囲内のコンテンツのみを含めるかを定義します。
コンテンツの抽出 メソッドの実装には ここ があります。この方法は、この記事のシナリオで参照されます。
また、抽出されたノードからドキュメントを簡単に生成するためのカスタム メソッドも定義します。このメソッドは、以下の多くのシナリオで使用され、単純に新しいドキュメントを作成し、抽出されたコンテンツをそこにインポートします。
次のコード例は、ノードのリストを取得して新しいドキュメントに挿入する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
@staticmethod | |
def generate_document(src_doc: aw.Document, nodes): | |
dst_doc = aw.Document() | |
# Remove the first paragraph from the empty document. | |
dst_doc.first_section.body.remove_all_children() | |
# Import each node from the list into the new document. Keep the original formatting of the node. | |
importer = aw.NodeImporter(src_doc, dst_doc, aw.ImportFormatMode.KEEP_SOURCE_FORMATTING) | |
for node in nodes: | |
import_node = importer.import_node(node, True) | |
dst_doc.first_section.body.append_child(import_node) | |
return dst_doc |
段落間のコンテンツを抽出する
これは、上記のメソッドを使用して特定の段落間のコンテンツを抽出する方法を示しています。この場合、文書の前半にある手紙の本文を抽出したいと考えています。これは 7 番目の段落と 11 番目の段落の間にあることがわかります。
以下のコードはこのタスクを実行します。ドキュメント上で CompositeNode.get_child メソッドを使用し、指定されたインデックスを渡すことで、適切な段落が抽出されます。次に、これらのノードを コンテンツの抽出 メソッドに渡し、これらのノードが抽出に含まれることを示します。このメソッドは、これらのノード間でコピーされたコンテンツを返し、新しいドキュメントに挿入されます。
次のコード例は、上記の コンテンツの抽出 メソッドを使用して特定の段落間のコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
start_para = doc.first_section.body.get_child(aw.NodeType.PARAGRAPH, 6, True).as_paragraph() | |
end_para = doc.first_section.body.get_child(aw.NodeType.PARAGRAPH, 10, True).as_paragraph() | |
# Extract the content between these nodes in the document. Include these markers in the extraction. | |
extracted_nodes = helper.ExtractContentHelper.extract_content(start_para, end_para, True) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_paragraphs.docx") |
異なるタイプのノード間でコンテンツを抽出する
ブロック レベルまたはインライン ノードの任意の組み合わせの間でコンテンツを抽出できます。以下のこのシナリオでは、最初の段落と 2 番目のセクションの表の間のコンテンツを包括的に抽出します。ドキュメントの 2 番目のセクションで Body.first_paragraph および CompositeNode.get_child メソッドを呼び出して、適切な Paragraph ノードと Table ノードを取得することにより、マーカー ノードを取得します。わずかなバリエーションとして、代わりにコンテンツを複製し、元のものの下に挿入してみましょう。
次のコード例は、コンテンツの抽出 メソッドを使用して段落と表の間のコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
start_para = doc.last_section.get_child(aw.NodeType.PARAGRAPH, 2, True).as_paragraph() | |
end_table = doc.last_section.get_child(aw.NodeType.TABLE, 0, True).as_table() | |
# Extract the content between these nodes in the document. Include these markers in the extraction. | |
extracted_nodes = helper.ExtractContentHelper.extract_content(start_para, end_table, True) | |
# Let's reverse the array to make inserting the content back into the document easier. | |
extracted_nodes.reverse() | |
for extracted_node in extracted_nodes: | |
end_table.parent_node.insert_after(extracted_node, end_table) | |
doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_block_level_nodes.docx") |
スタイルに基づいて段落間のコンテンツを抽出する
見出しスタイルでマークされた段落間など、同じまたは異なるスタイルの段落間でコンテンツを抽出する必要がある場合があります。
以下のコードは、これを実現する方法を示しています。これは、見出しを抽出せずに、「見出し 1」スタイルと「見出し 3」スタイルの最初のインスタンスの間のコンテンツを抽出する簡単な例です。これを行うには、最後のパラメータを false に設定します。これは、マーカー ノードを含めないことを指定します。
適切な実装では、これをループ内で実行して、ドキュメントからこれらのスタイルのすべての段落間のコンテンツを抽出する必要があります。抽出されたコンテンツは新しいドキュメントにコピーされます。
次のコード例は、コンテンツの抽出 メソッドを使用して特定のスタイルで段落間のコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
# Gather a list of the paragraphs using the respective heading styles. | |
paras_style_heading1 = self.paragraphs_by_style_name(doc, "Heading 1") | |
paras_style_heading3 = self.paragraphs_by_style_name(doc, "Heading 3") | |
# Use the first instance of the paragraphs with those styles. | |
start_para1 = paras_style_heading1[0] | |
end_para1 = paras_style_heading3[0] | |
# Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
extracted_nodes = helper.ExtractContentHelper.extract_content(start_para1, end_para1, False) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_paragraph_styles.docx") |
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
@staticmethod | |
def paragraphs_by_style_name(doc: aw.Document, style_name: str): | |
# Create an array to collect paragraphs of the specified style. | |
paragraphs_with_style = [] | |
paragraphs = doc.get_child_nodes(aw.NodeType.PARAGRAPH, True) | |
# Look through all paragraphs to find those with the specified style. | |
for paragraph in paragraphs: | |
paragraph = paragraph.as_paragraph() | |
if paragraph.paragraph_format.style.name == style_name: | |
paragraphs_with_style.append(paragraph) | |
return paragraphs_with_style |
特定の実行間のコンテンツの抽出
Run などのインライン ノード間でもコンテンツを抽出できます。異なる段落からの連続をマーカーとして渡すことができます。以下のコードは、同じ Paragraph ノード間の特定のテキストを抽出する方法を示しています。
次のコード例は、コンテンツの抽出 メソッドを使用して、同じ段落の特定の実行の間でコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
para = doc.get_child(aw.NodeType.PARAGRAPH, 7, True).as_paragraph() | |
start_run = para.runs[1] | |
end_run = para.runs[4] | |
# Extract the content between these nodes in the document. Include these markers in the extraction. | |
extracted_nodes = helper.ExtractContentHelper.extract_content(start_run, end_run, True) | |
for extracted_node in extracted_nodes: | |
print(extracted_node.to_string(aw.SaveFormat.TEXT)) |
フィールドを使用してコンテンツを抽出する
フィールドをマーカーとして使用するには、FieldStart ノードを渡す必要があります。 コンテンツの抽出 メソッドの最後のパラメータは、フィールド全体を含めるかどうかを定義します。文書内の「FullName」差し込みフィールドと段落の間のコンテンツを抽出してみましょう。 DocumentBuilderクラスのDocumentBuilder.move_to_merge_fieldメソッドを使用します。これにより、渡された差し込みフィールドの名前から FieldStart ノードが返されます。
この例では、コンテンツの抽出 メソッドに渡される最後のパラメータを False
に設定して、フィールドを抽出から除外しましょう。抽出したコンテンツを PDF にレンダリングします。
次のコード例は、コンテンツの抽出 メソッドを使用してドキュメント内の特定のフィールドと段落の間のコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
builder = aw.DocumentBuilder(doc) | |
# Pass the first boolean parameter to get the DocumentBuilder to move to the FieldStart of the field. | |
# We could also get FieldStarts of a field using GetChildNode method as in the other examples. | |
builder.move_to_merge_field("Fullname", False, False) | |
# The builder cursor should be positioned at the start of the field. | |
start_field = builder.current_node.as_field_start() | |
end_para = doc.first_section.get_child(aw.NodeType.PARAGRAPH, 5, True).as_paragraph() | |
# Extract the content between these nodes in the document. Don't include these markers in the extraction. | |
extracted_nodes = helper.ExtractContentHelper.extract_content(start_field, end_para, False) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_using_field.docx") |
ブックマークからコンテンツを抽出する
ドキュメントでは、ブックマーク内で定義されたコンテンツは、BookmarkStart ノードと BookmarkEnd ノードによってカプセル化されます。これら 2 つのノードの間にあるコンテンツがブックマークを構成します。ドキュメント内で開始マーカーが終了マーカーより前に表示される限り、これらのノードのいずれかを任意のマーカーとして渡すことができます。異なるブックマークのマーカーであっても同様です。以下のコードを使用して、このコンテンツを新しいドキュメントに抽出します。 包括的です パラメーター オプションは、ブックマークを保持または破棄する方法を示します。
次のコード例は、コンテンツの抽出 メソッドを使用してブックマークを参照しているコンテンツを抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
bookmark = doc.range.bookmarks.get_by_name("Bookmark1") | |
bookmark_start = bookmark.bookmark_start | |
bookmark_end = bookmark.bookmark_end | |
# Firstly, extract the content between these nodes, including the bookmark. | |
extracted_nodes_inclusive = helper.ExtractContentHelper.extract_content(bookmark_start, bookmark_end, True) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes_inclusive) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_bookmark.including_bookmark.docx") | |
# Secondly, extract the content between these nodes this time without including the bookmark. | |
extracted_nodes_exclusive = helper.ExtractContentHelper.extract_content(bookmark_start, bookmark_end, False) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes_exclusive) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_bookmark.without_bookmark.docx") |
コメントからコンテンツを抽出する
コメントは、CommentRangeStart、CommentRangeEnd、および Comment ノードで構成されます。これらのノードはすべてインラインです。以下のスクリーンショットに示すように、最初の 2 つのノードは、コメントによって参照されるドキュメント内のコンテンツをカプセル化します。 Comment ノード自体は、段落とランを含めることができる InlineStory です。これは、レビュー ペインのコメント バブルとして表示されるコメントのメッセージを表します。このノードはインラインで本文の子孫であるため、このメッセージ内からコンテンツを抽出することもできます。
コメントは、見出し、最初の段落、および 2 番目のセクションの表をカプセル化します。このコメントを新しいドキュメントに抽出してみましょう。 包括的です オプションは、コメント自体を保持するか破棄するかを決定します。
次のコード例は、これを行う方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Extract content.docx") | |
comment_start = doc.get_child(aw.NodeType.COMMENT_RANGE_START, 0, True).as_comment_range_start() | |
comment_end = doc.get_child(aw.NodeType.COMMENT_RANGE_END, 0, True).as_comment_range_end() | |
# Firstly, extract the content between these nodes including the comment as well. | |
extracted_nodes_inclusive = helper.ExtractContentHelper.extract_content(comment_start, comment_end, True) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes_inclusive) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_comment_range.including_comment.docx") | |
# Secondly, extract the content between these nodes without the comment. | |
extracted_nodes_exclusive = helper.ExtractContentHelper.extract_content(comment_start, comment_end, False) | |
dst_doc = helper.ExtractContentHelper.generate_document(doc, extracted_nodes_exclusive) | |
dst_doc.save(ARTIFACTS_DIR + "ExtractContent.extract_content_between_comment_range.without_comment.docx") |
テキストのみを抽出する方法
ドキュメントからテキストを取得する方法は次のとおりです。
- Document.save を使用してプレーンテキストとしてファイルまたはストリームに保存します
- Node.to_string を使用し、SaveFormat.TEXT パラメータを渡します。内部的には、メモリ ストリームへのテキストとして保存を呼び出し、結果の文字列を返します。
- Node.get_text を使用して、フィールド コードを含むすべての Microsoft Word 制御文字を含むテキストを取得します
Node.get_text と Node.to_string の使用
Word 文書には、フィールド、セルの終わり、セクションの終わりなどの特別な要素を指定する制御文字を含めることができます。使用可能な Word 制御文字の完全なリストは、ControlChar クラスで定義されています。 Node.get_text メソッドは、ノード内に存在するすべての制御文字を含むテキストを返します。
to_string を呼び出すと、制御文字を含まないドキュメントのプレーン テキスト表現のみが返されます。プレーン テキストとしてのエクスポートの詳細については、「SaveFormat.TEXT の使用」を参照してください。
次のコード例は、ノードでの get_text メソッドと to_string メソッドの呼び出しの違いを示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document() | |
builder = aw.DocumentBuilder(doc) | |
builder.insert_field("MERGEFIELD Field") | |
# When converted to text it will not retrieve fields code or special characters, | |
# but will still contain some natural formatting characters such as paragraph markers etc. | |
# This is the same as "viewing" the document as if it was opened in a text editor. | |
print("ToString() Result: " + doc.to_string(aw.SaveFormat.TEXT)) |
SaveFormat.Text
の使用
この例では、ドキュメントを次のように保存します。
- フィールド文字とフィールドコード、形状、脚注、文末脚注、およびコメント参照をフィルタリングして除外します。
- 段落の終わりの ControlChar.Cr 文字を ControlChar.CrLf の組み合わせに置き換えます
- UTF8エンコーディングを使用します
次のコード例は、ドキュメントを TXT 形式で保存する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Document.docx") | |
doc.save(ARTIFACTS_DIR + "BaseConversions.docx_to_txt.txt") |
図形から画像を抽出する
一部のタスクを実行するには、ドキュメント画像を抽出する必要がある場合があります。 Aspose.Words を使用すると、これも行うことができます。
次のコード例は、ドキュメントから画像を抽出する方法を示しています。
# For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Python-via-.NET.git. | |
doc = aw.Document(MY_DIR + "Images.docx") | |
shapes = doc.get_child_nodes(aw.NodeType.SHAPE, True) | |
image_index = 0 | |
for shape in shapes: | |
shape = shape.as_shape() | |
if shape.has_image: | |
image_extension = aw.FileFormatUtil.image_type_to_extension(shape.image_data.image_type) | |
image_file_name = "Image.ExportImages." + str(image_index) + image_extension | |
# Note, if you have only an image (not a shape with a text and the image), | |
# you can use shape.get_shape_renderer().save(...) method to save the image. | |
shape.image_data.save(ARTIFACTS_DIR + image_file_name) | |
image_index += 1 |