ドキュメント内のノード間でコンテンツを抽出する

ドキュメントを操作するときは、ドキュメント内の特定の範囲からコンテンツを簡単に抽出できることが重要です。 ただし、コンテンツは、段落、表、画像などの複雑な要素で構成されている場合があります。

どのコンテンツを抽出する必要があるかにかかわらず、そのコンテンツを抽出する方法は、コンテンツを抽出するために選択されたノードによって常に決定されます。 これらは、テキスト本文全体または単純なテキスト実行にすることができます。

多くの可能な状況があるため、コンテンツを抽出する際に考慮すべき多くの異なるノードタイプがあります。 たとえば、次の間でコンテンツを抽出することができます:

  • 二つの特定の段落
  • テキストの特定の実行
  • 差し込み項目など、さまざまなタイプの項目
  • ブックマークまたはコメントの開始範囲と終了範囲
  • 別のセクションに含まれるテキストのさまざまなボディ

状況によっては、段落とフィールドの間、または実行とブックマークの間のコンテンツの抽出など、異なるノードタイプを組み合わせる必要がある場合もあ

この記事では、異なるノード間でテキストを抽出するためのコード実装と、一般的なシナリオの例について説明します。

なぜコンテンツを抽出するのか

多くの場合、コンテンツを抽出する目的は、コンテンツを複製または新しいドキュメントに個別に保存することです。 たとえば、コンテンツを抽出することができます。:

  • 別の文書にコピーします
  • 文書の特定の部分をPDFまたは画像に変換する
  • ドキュメント内のコンテンツを何度も複製します
  • ドキュメントの残りの部分とは別に抽出されたコンテンツを操作します

これは、Aspose.Wordsと以下のコード実装を使用して簡単に実現できます。

コンテンツの抽出アルゴリズム

このセクションのコードは、1つの一般化された再利用可能な方法で、上記のすべての状況に対処します。 この手法の一般的な概要には、次のものが含まれます:

  1. ドキュメントから抽出されるコンテンツの領域を指示するノードを収集します。 これらのノードの取得は、抽出したいものに基づいて、コード内のユーザーによって処理されます。
  2. これらのノードを以下に示すExtractContentメソッドに渡します。 また、マーカーとして機能するこれらのノードを抽出に含めるかどうかを示すbooleanパラメータを渡す必要があります。
  3. 抽出されるように指定された複製されたコンテンツ(コピーされたノード)のリストを取得します。 このノードのリストは、選択したコンテンツのみを含む新しいドキュメントを作成するなど、任意の適用可能な方法で使用できます。

コンテンツを抽出する方法

ドキュメントからコンテンツを抽出するには、以下のExtractContentメソッドを呼び出し、適切なパラメータを渡す必要があります。 この方法の基礎となる基礎には、ブロックレベルのノード(段落と表)を見つけて、それらを複製して同一のコピーを作成することが含まれます。 渡されたマーカーノードがブロックレベルの場合、メソッドはそのレベルのコンテンツを単純にコピーして配列に追加することができます。

ただし、マーカーノードがインライン(段落の子)の場合、インラインノードで段落を分割する必要があるため、状況はより複雑になります。 マーカーの間に存在しない複製された親ノード内のコンテンツは削除されます。 このプロセスは、インラインノードが親段落の書式設定を保持することを保証するために使用されます。 このメソッドは、パラメーターとして渡されたノードでもチェックを実行し、いずれかのノードが無効な場合は例外をスローします。 このメソッドに渡されるパラメータは次のとおりです:

  1. StartNodeEndNode。 最初の2つのパラメータは、コンテンツの抽出を開始する場所と終了する場所をそれぞれ定義するノードです。 これらのノードは、ブロックレベル(段落、テーブル)またはインラインレベル(Run、FieldStart、BookmarkStartなど)の両方にすることができます。):

    1. フィールドを渡すには、対応するFieldStartオブジェクトを渡す必要があります。
    2. ブックマークを渡すには、BookmarkStartノードとBookmarkEndノードを渡す必要があります。
    3. コメントを渡すには、CommentRangeStartノードとCommentRangeEndノードを使用する必要があります。
  2. IsInclusive. マーカーが抽出に含まれるかどうかを定義します。 このオプションがfalseに設定されていて、同じノードまたは連続したノードが渡された場合、空のリストが返されます:

    1. FieldStartノードが渡された場合、このオプションはフィールド全体を含めるか除外するかを定義します。
    2. BookmarkStartまたはBookmarkEndノードが渡された場合、このオプションはブックマークが含まれているか、ブックマーク範囲の間のコンテンツのみを定義します。
    3. CommentRangeStartまたはCommentRangeEndノードが渡された場合、このオプションはコメント自体を含めるか、コメント範囲内のコンテンツのみを定義します。

あなたが見つけることができるExtractContentメソッドの実装 ここに. この方法については、この記事のシナリオで説明します。

また、抽出されたノードからドキュメントを簡単に生成するためのカスタムメソッドも定義します。 このメソッドは、以下のシナリオの多くで使用され、単純に新しいドキュメントを作成し、抽出されたコンテンツをインポートします。

次のコード例は、ノードのリストを取得して新しいドキュメントに挿入する方法を示しています。

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
static SharedPtr<Document> GenerateDocument(SharedPtr<Document> srcDoc, SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> nodes)
{
auto dstDoc = MakeObject<Document>();
// Remove the first paragraph from the empty document.
dstDoc->get_FirstSection()->get_Body()->RemoveAllChildren();
// Import each node from the list into the new document. Keep the original formatting of the node.
auto importer = MakeObject<NodeImporter>(srcDoc, dstDoc, ImportFormatMode::KeepSourceFormatting);
for (const auto& node : nodes)
{
SharedPtr<Node> importNode = importer->ImportNode(node, true);
dstDoc->get_FirstSection()->get_Body()->AppendChild(importNode);
}
return dstDoc;
}

段落間のコンテンツの抽出

これは、上記の方法を使用して特定の段落間のコンテンツを抽出する方法を示しています。 この場合、文書の前半に見つかった文字の本文を抽出します。 これは7番目と11番目の段落の間にあることがわかります。

以下のコードは、このタスクを実行します。 適切な段落は、文書上のGetChildメソッドを使用して抽出され、指定されたインデックスを渡します。 次に、これらのノードをExtractContentメソッドに渡し、これらが抽出に含まれることを示します。 このメソッドは、これらのノード間でコピーされたコンテンツを返し、新しいドキュメントに挿入します。

次のコード例は、上記のExtractContentメソッドを使用して特定の段落間のコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto startPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 6, true));
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->get_Body()->GetChild(NodeType::Paragraph, 10, true));
// Extract the content between these nodes in the document. Include these markers in the extraction.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endPara, true);
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphs.docx");

異なるタイプのノード間でコンテンツを抽出する

ブロックレベルノードまたはインラインノードの任意の組み合わせの間でコンテンツを抽出できます。 以下のこのシナリオでは、最初の段落と2番目のセクションのテーブルの間のコンテンツを包括的に抽出します。 我々は適切な段落とテーブルノードを取得するために、文書の第二のセクションでBody.FirstParagraphGetChildメソッドを呼び出すことにより、マーカーノードを取得します。 わずかな変化のために、代わりにコンテンツを複製し、元の下に挿入してみましょう。

次のコード例は、ExtractContentメソッドを使用して段落とテーブルの間のコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto startPara = System::ExplicitCast<Paragraph>(doc->get_LastSection()->GetChild(NodeType::Paragraph, 2, true));
auto endTable = System::ExplicitCast<Table>(doc->get_LastSection()->GetChild(NodeType::Table, 0, true));
// Extract the content between these nodes in the document. Include these markers in the extraction.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara, endTable, true);
// Let's reverse the array to make inserting the content back into the document easier.
extractedNodes->Reverse();
for (SharedPtr<Node> extractedNode : extractedNodes)
// Insert the last node from the reversed list.
endTable->get_ParentNode()->InsertAfter(extractedNode, endTable);
doc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBlockLevelNodes.docx");

スタイルに基づいて段落間のコンテンツを抽出する

見出しスタイルでマークされた段落間など、同じスタイルまたは異なるスタイルの段落間のコンテンツを抽出する必要がある場合があります。 以下のコードは、これを達成する方法を示しています。 これは、見出しを抽出せずに、“Heading1"スタイルと"Header3"スタイルの最初のインスタンスの間のコンテンツを抽出する簡単な例です。 これを行うには、最後のパラメータをfalseに設定し、マーカーノードを含めるべきではないことを指定します。

適切な実装では、これをループで実行して、ドキュメントからこれらのスタイルのすべての段落の間のコンテンツを抽出する必要があります。 抽出されたコンテンツが新しいドキュメントにコピーされます。

次のコード例は、ExtractContentメソッドを使用して特定のスタイルを持つ段落間のコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
// Gather a list of the paragraphs using the respective heading styles.
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading1 = ParagraphsByStyleName(doc, u"Heading 1");
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> parasStyleHeading3 = ParagraphsByStyleName(doc, u"Heading 3");
// Use the first instance of the paragraphs with those styles.
SharedPtr<Node> startPara1 = parasStyleHeading1->idx_get(0);
SharedPtr<Node> endPara1 = parasStyleHeading3->idx_get(0);
// Extract the content between these nodes in the document. Don't include these markers in the extraction.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startPara1, endPara1, false);
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenParagraphStyles.docx");
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
static SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> ParagraphsByStyleName(SharedPtr<Document> doc, System::String styleName)
{
// Create an array to collect paragraphs of the specified style.
SharedPtr<System::Collections::Generic::List<SharedPtr<Paragraph>>> paragraphsWithStyle =
MakeObject<System::Collections::Generic::List<SharedPtr<Paragraph>>>();
SharedPtr<NodeCollection> paragraphs = doc->GetChildNodes(NodeType::Paragraph, true);
// Look through all paragraphs to find those with the specified style.
for (const auto& paragraph : System::IterateOver<Paragraph>(paragraphs))
{
if (paragraph->get_ParagraphFormat()->get_Style()->get_Name() == styleName)
{
paragraphsWithStyle->Add(paragraph);
}
}
return paragraphsWithStyle;
}

特定の実行間でコンテンツを抽出する

Runなどのインラインノード間でコンテンツを抽出することもできます。 異なる段落のRunsをマーカーとして渡すことができます。 以下のコードは、同じParagraphノードの間にある特定のテキストを抽出する方法を示しています。

次のコード例は、ExtractContentメソッドを使用して、同じ段落の特定の実行間でコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto para = System::ExplicitCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 7, true));
SharedPtr<Run> startRun = para->get_Runs()->idx_get(1);
SharedPtr<Run> endRun = para->get_Runs()->idx_get(4);
// Extract the content between these nodes in the document. Include these markers in the extraction.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startRun, endRun, true);
for (SharedPtr<Node> extractedNode : extractedNodes)
std::cout << extractedNode->ToString(SaveFormat::Text) << std::endl;

フィールドを使用したコンテンツの抽出

フィールドをマーカーとして使用するには、FieldStartノードを渡す必要があります。 ExtractContentメソッドの最後のパラメータは、フィールド全体を含めるかどうかを定義します。 “FullName"差し込み項目と文書内の段落の間の内容を抽出してみましょう。 私たちはDocumentBuilderクラスのMoveToMergeFieldメソッドを使用します。 これにより、渡された差し込み項目の名前からFieldStartノードが返されます。

この例では、ExtractContentメソッドに渡された最後のパラメータをfalseに設定して、フィールドを抽出から除外しましょう。 抽出されたコンテンツをPDFにレンダリングします。

次のコード例は、ExtractContentメソッドを使用して、ドキュメント内の特定のフィールドと段落の間のコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto builder = MakeObject<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->MoveToMergeField(u"Fullname", false, false);
// The builder cursor should be positioned at the start of the field.
auto startField = System::ExplicitCast<FieldStart>(builder->get_CurrentNode());
auto endPara = System::ExplicitCast<Paragraph>(doc->get_FirstSection()->GetChild(NodeType::Paragraph, 5, true));
// Extract the content between these nodes in the document. Don't include these markers in the extraction.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodes = ExtractContentHelper::ExtractContent(startField, endPara, false);
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodes);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentUsingField.docx");

ブックマークからコンテンツを抽出する

ドキュメントでは、ブックマーク内で定義されているコンテンツは、BookmarkStartノードとBookmarkEndノードによってカプセル化されます。 これらの2つのノードの間にあるコンテンツがブックマークを構成します。 開始マーカーがドキュメント内の終了マーカーの前に表示されている限り、これらのノードのいずれかを任意のマーカーとして渡すことができます。 以下のコードを使用して、このコンテンツを新しいドキュメントに抽出します。 IsInclusiveパラメータオプションは、ブックマークを保持または破棄する方法を示します。

次のコード例は、ExtractContentメソッドを使用してブックマークを参照しているコンテンツを抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
SharedPtr<Bookmark> bookmark = doc->get_Range()->get_Bookmarks()->idx_get(u"Bookmark1");
SharedPtr<BookmarkStart> bookmarkStart = bookmark->get_BookmarkStart();
SharedPtr<BookmarkEnd> bookmarkEnd = bookmark->get_BookmarkEnd();
// Firstly, extract the content between these nodes, including the bookmark.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive =
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, true);
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.IncludingBookmark.docx");
// Secondly, extract the content between these nodes this time without including the bookmark.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive =
ExtractContentHelper::ExtractContent(bookmarkStart, bookmarkEnd, false);
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenBookmark.WithoutBookmark.docx");

コメントからコンテンツを抽出する

コメントは、CommentRangeStart、CommentRangeEnd、およびコメントノードで構成されます。 これらのノードはすべてインラインです。 最初の2つのノードは、下のスクリーンショットに示されているように、コメントによって参照されるドキュメント内のコンテンツをカプセル化します。

Commentノード自体は、段落と実行を含めることができるInlineStoryです。 これは、プレビューペインでコメントバブルとして表示されるコメントのメッセージを表します。 このノードはインラインであり、本文の子孫であるため、このメッセージ内からコンテンツを抽出することもできます。

コメントは、見出し、最初の段落、および2番目のセクションのテーブルをカプセル化します。 このコメントを新しい文書に抽出しましょう。 IsInclusiveオプションは、コメント自体が保持されるか破棄されるかを指定します。

次のコード例は、これを行う方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto commentStart = System::ExplicitCast<CommentRangeStart>(doc->GetChild(NodeType::CommentRangeStart, 0, true));
auto commentEnd = System::ExplicitCast<CommentRangeEnd>(doc->GetChild(NodeType::CommentRangeEnd, 0, true));
// Firstly, extract the content between these nodes including the comment as well.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesInclusive =
ExtractContentHelper::ExtractContent(commentStart, commentEnd, true);
SharedPtr<Document> dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesInclusive);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.IncludingComment.docx");
// Secondly, extract the content between these nodes without the comment.
SharedPtr<System::Collections::Generic::List<SharedPtr<Node>>> extractedNodesExclusive =
ExtractContentHelper::ExtractContent(commentStart, commentEnd, false);
dstDoc = ExtractContentHelper::GenerateDocument(doc, extractedNodesExclusive);
dstDoc->Save(ArtifactsDir + u"ExtractContent.ExtractContentBetweenCommentRange.WithoutComment.docx");

DocumentVisitorを使用してコンテンツを抽出する方法

この使用シナリオを実装するには、DocumentVisitorクラスを使用します。 このクラスは、よく知られている訪問者のデザインパターンに対応しています。 **DocumentVisitor,**を使用すると、ドキュメントツリー上で列挙を必要とするカスタム操作を定義して実行できます。

DocumentVisitor

DocumentVisitor.VisitXXXメソッドは、ノードの列挙を制御するVisitorAction値を返します。 列挙を続行するか、現在のノードをスキップする(ただし列挙を続行する)か、またはノードの列挙を停止するように要求できます。

次の手順は、ドキュメントのさまざまな部分をプログラムで決定して抽出するために実行する必要があります:

  • DocumentVisitorから派生したクラスを作成します
  • いくつかのカスタム操作を実行するためにDocumentVisitor.VisitXXXメソッドの一部またはすべての実装をオーバーライドして提供します
  • 列挙を開始するノードでNode.Acceptを呼び出します。 たとえば、文書全体を列挙する場合は、Document.Acceptを使用します

DocumentVisitor

この例では、ビジターパターンを使用してAspose.Wordsオブジェクトモデルに新しい操作を追加する方法を示します。 この場合、単純なドキュメントコンバータをテキスト形式に作成します:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Extract content.docx");
auto convertToPlainText = MakeObject<ExtractContent::ConvertDocToTxt>();
// Note that every node in the object model has the accept method so the visiting
// can be executed not only for the whole document, but for any node in the document.
doc->Accept(convertToPlainText);
// Once the visiting is complete, we can retrieve the result of the operation,
// That in this example, has accumulated in the visitor.
std::cout << convertToPlainText->GetText() << std::endl;
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
/// <summary>
/// Simple implementation of saving a document in the plain text format. Implemented as a Visitor.
/// </summary>
class ConvertDocToTxt : public DocumentVisitor
{
public:
ConvertDocToTxt() : mIsSkipText(false)
{
mIsSkipText = false;
mBuilder = MakeObject<System::Text::StringBuilder>();
}
/// <summary>
/// Gets the plain text of the document that was accumulated by the visitor.
/// </summary>
String GetText()
{
return mBuilder->ToString();
}
/// <summary>
/// Called when a Run node is encountered in the document.
/// </summary>
VisitorAction VisitRun(SharedPtr<Run> run) override
{
AppendText(run->get_Text());
// Let the visitor continue visiting other nodes.
return VisitorAction::Continue;
}
/// <summary>
/// Called when a FieldStart node is encountered in the document.
/// </summary>
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
ASPOSE_UNUSED(fieldStart);
// In Microsoft Word, a field code (such as "MERGEFIELD FieldName") follows
// after a field start character. We want to skip field codes and output field.
// Result only, therefore we use a flag to suspend the output while inside a field code.
// Note this is a very simplistic implementation and will not work very well.
// If you have nested fields in a document.
mIsSkipText = true;
return VisitorAction::Continue;
}
/// <summary>
/// Called when a FieldSeparator node is encountered in the document.
/// </summary>
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
ASPOSE_UNUSED(fieldSeparator);
// Once reached a field separator node, we enable the output because we are
// now entering the field result nodes.
mIsSkipText = false;
return VisitorAction::Continue;
}
/// <summary>
/// Called when a FieldEnd node is encountered in the document.
/// </summary>
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
ASPOSE_UNUSED(fieldEnd);
// Make sure we enable the output when reached a field end because some fields
// do not have field separator and do not have field result.
mIsSkipText = false;
return VisitorAction::Continue;
}
/// <summary>
/// Called when visiting of a Paragraph node is ended in the document.
/// </summary>
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
ASPOSE_UNUSED(paragraph);
// When outputting to plain text we output Cr+Lf characters.
AppendText(ControlChar::CrLf());
return VisitorAction::Continue;
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
ASPOSE_UNUSED(body);
// We can detect beginning and end of all composite nodes such as Section, Body,
// Table, Paragraph etc and provide custom handling for them.
mBuilder->Append(u"*** Body Started ***\r\n");
return VisitorAction::Continue;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
ASPOSE_UNUSED(body);
mBuilder->Append(u"*** Body Ended ***\r\n");
return VisitorAction::Continue;
}
/// <summary>
/// Called when a HeaderFooter node is encountered in the document.
/// </summary>
VisitorAction VisitHeaderFooterStart(SharedPtr<HeaderFooter> headerFooter) override
{
ASPOSE_UNUSED(headerFooter);
// Returning this value from a visitor method causes visiting of this
// Node to stop and move on to visiting the next sibling node
// The net effect in this example is that the text of headers and footers
// Is not included in the resulting output
return VisitorAction::SkipThisNode;
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
bool mIsSkipText;
/// <summary>
/// Adds text to the current output. Honors the enabled/disabled output flag.
/// </summary>
void AppendText(String text)
{
if (!mIsSkipText)
{
mBuilder->Append(text);
}
}
};

テキストのみを抽出する方法

文書からテキストを取得する方法は次のとおりです:

  • プレーンテキストとしてファイルまたはストリームに保存するには、Document.SaveSaveFormat.Textを使用します
  • Node.ToStringを使用して、SaveFormat.Textパラメータを渡します。 内部的には、これはsave as textをメモリストリームに呼び出し、結果の文字列を返します
  • Node.GetTextを使用して、フィールドコードを含むすべてのMicrosoft Word制御文字を含むテキストを取得します
  • カスタムDocumentVisitorを実装して、カスタマイズされた抽出を実行します

Node.GetTextNode.ToStringを使用する

Word文書には、フィールド、セルの終わり、セクションの終わりなどの特別な要素を指定する制御文字を含めることができます。 使用可能な単語制御文字の完全なリストは、ControlCharクラスで定義されています。 Node.GetTextメソッドは、ノード内に存在するすべての制御文字を含むテキストを返します。

ToStringを呼び出すと、制御文字を含まない文書のプレーンテキスト表現のみが返されます。

次のコード例は、ノードでGetTextメソッドとToStringメソッドを呼び出す際の違いを示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->InsertField(u"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.
std::cout << (String(u"ToString() Result: ") + doc->ToString(SaveFormat::Text)) << std::endl;

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-C.git.
auto doc = MakeObject<Document>(MyDir + u"Document.docx");
doc->Save(ArtifactsDir + u"BaseConversions.DocxToTxt.txt");
view raw docx-to-txt.h hosted with ❤ by GitHub

図形から画像を抽出する

いくつかのタスクを実行するには、ドキュメントイメージを抽出する必要がある場合があります。 Aspose.Wordsを使用すると、これも行うことができます。

次のコード例は、ドキュメントから画像を抽出する方法を示しています:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-C.git.
auto doc = MakeObject<Document>(MyDir + u"Images.docx");
SharedPtr<NodeCollection> shapes = doc->GetChildNodes(NodeType::Shape, true);
int imageIndex = 0;
for (const auto& shape : System::IterateOver<Shape>(shapes))
{
if (shape->get_HasImage())
{
String imageFileName =
String::Format(u"Image.ExportImages.{0}_{1}", imageIndex, FileFormatUtil::ImageTypeToExtension(shape->get_ImageData()->get_ImageType()));
// Note, if you have only an image (not a shape with a text and the image),
// you can use shape->GetShapeRenderer()->Save(...) method to save the image.
shape->get_ImageData()->Save(ArtifactsDir + imageFileName);
imageIndex++;
}
}