Extrahieren von Inhalten zwischen Knoten in einem Dokument
Bei der Arbeit mit Dokumenten ist es wichtig, Inhalte aus einem bestimmten Bereich innerhalb eines Dokuments einfach extrahieren zu können. Der Inhalt kann jedoch aus komplexen Elementen wie Absätzen, Tabellen, Bildern usw. bestehen.
Unabhängig davon, welcher Inhalt extrahiert werden muss, wird die Methode zum Extrahieren dieses Inhalts immer dadurch bestimmt, zwischen welchen Knoten Inhalte extrahiert werden sollen. Dies können ganze Textkörper oder einfache Textläufe sein.
Es gibt viele mögliche Situationen und daher viele verschiedene Knotentypen, die beim Extrahieren von Inhalten berücksichtigt werden müssen. Beispielsweise möchten Sie möglicherweise Inhalte extrahieren zwischen:
- Zwei spezifische Absätze
- Spezifische Textläufe
- Felder verschiedener Typen, z. B. Seriendruckfelder
- Anfangs- und Endbereich eines Lesezeichens oder Kommentars
- Verschiedene Textkörper, die in separaten Abschnitten enthalten sind
In einigen Situationen müssen Sie möglicherweise sogar verschiedene Knotentypen kombinieren, z. B. das Extrahieren von Inhalten zwischen einem Absatz und einem Feld oder zwischen einem Lauf und einem Lesezeichen.
Dieser Artikel enthält die Codeimplementierung zum Extrahieren von Text zwischen verschiedenen Knoten sowie Beispiele für gängige Szenarien.
Warum Inhalte extrahieren
Oft besteht das Ziel des Extrahierens des Inhalts darin, ihn zu duplizieren oder separat in einem neuen Dokument zu speichern. Sie können beispielsweise Inhalte extrahieren und:
- Kopieren Sie es in ein separates Dokument
- Konvertieren Sie einen bestimmten Teil eines Dokuments in PDF oder ein Bild
- Duplizieren Sie den Inhalt des Dokuments mehrmals
- Arbeiten Sie mit extrahiertem Inhalt getrennt vom Rest des Dokuments
Dies kann leicht mit Aspose.Words und der folgenden Code-Implementierung erreicht werden.
Algorithmus zum Extrahieren von Inhalten
Der Code in diesem Abschnitt behandelt alle oben beschriebenen möglichen Situationen mit einer verallgemeinerten und wiederverwendbaren Methode. Der allgemeine Überblick über diese Technik beinhaltet:
- Sammeln der Knoten, die den Inhaltsbereich vorgeben, der aus Ihrem Dokument extrahiert wird. Das Abrufen dieser Knoten wird vom Benutzer in seinem Code basierend auf dem, was extrahiert werden soll, gehandhabt.
- Übergeben dieser Knoten an die unten angegebene ExtractContent -Methode. Sie müssen auch einen booleschen Parameter übergeben, der angibt, ob diese Knoten, die als Marker fungieren, in die Extraktion einbezogen werden sollen oder nicht.
- Abrufen einer Liste geklonter Inhalte (kopierter Knoten), die extrahiert werden sollen. Sie können diese Knotenliste auf beliebige Weise verwenden, z. B. um ein neues Dokument zu erstellen, das nur den ausgewählten Inhalt enthält.
So extrahieren Sie Inhalte
Um den Inhalt aus Ihrem Dokument zu extrahieren, müssen Sie die unten stehende Methode ExtractContent
aufrufen und die entsprechenden Parameter übergeben. Die zugrunde liegende Grundlage dieser Methode besteht darin, Knoten auf Blockebene (Absätze und Tabellen) zu finden und sie zu klonen, um identische Kopien zu erstellen. Wenn die übergebenen Markerknoten Blockebene sind, kann die Methode den Inhalt auf dieser Ebene einfach kopieren und dem Array hinzufügen.
Wenn die Markerknoten jedoch inline sind (ein untergeordnetes Element eines Absatzes), wird die Situation komplexer, da der Absatz am Inline-Knoten aufgeteilt werden muss, sei es ein Lauf, Lesezeichenfelder usw. Inhalt in den geklonten übergeordneten Knoten, der nicht zwischen den Markern vorhanden ist, wird entfernt. Dieser Prozess wird verwendet, um sicherzustellen, dass die Inline-Knoten weiterhin die Formatierung des übergeordneten Absatzes beibehalten. Die Methode führt auch Überprüfungen der als Parameter übergebenen Knoten durch und löst eine Ausnahme aus, wenn einer der Knoten ungültig ist. Die Parameter, die an diese Methode übergeben werden sollen, sind:
-
StartNode und EndNode. Die ersten beiden Parameter sind die Knoten, die definieren, wo die Extraktion des Inhalts beginnen bzw. enden soll. Diese Knoten können sowohl Blockebene (Absatz, Tabelle) als auch Inline-Ebene (z. B. Ausführen, FieldStart, BookmarkStart usw.) sein.):
- Um ein Feld zu übergeben, sollten Sie das entsprechende FieldStart -Objekt übergeben.
- Um Lesezeichen zu übergeben, sollten die Knoten BookmarkStart und BookmarkEnd übergeben werden.
- Um Kommentare zu übergeben, sollten die Knoten CommentRangeStart und CommentRangeEnd verwendet werden.
-
IsInclusive. Definiert, ob die Marker in die Extraktion einbezogen werden oder nicht. Wenn diese Option auf false gesetzt ist und derselbe Knoten oder aufeinanderfolgende Knoten übergeben werden, wird eine leere Liste zurückgegeben:
- Wenn ein FieldStart-Knoten übergeben wird, definiert diese Option, ob das gesamte Feld eingeschlossen oder ausgeschlossen werden soll.
- Wenn ein BookmarkStart- oder BookmarkEnd-Knoten übergeben wird, definiert diese Option, ob das Lesezeichen enthalten ist oder nur der Inhalt zwischen dem Lesezeichenbereich.
- Wenn ein CommentRangeStart- oder CommentRangeEnd-Knoten übergeben wird, definiert diese Option, ob der Kommentar selbst oder nur der Inhalt in den Kommentarbereich aufgenommen werden soll.
Die Implementierung der ExtractContent -Methode finden Sie hier. Auf diese Methode wird in den Szenarien in diesem Artikel Bezug genommen.
Wir werden auch eine benutzerdefinierte Methode definieren, um auf einfache Weise ein Dokument aus extrahierten Knoten zu generieren. Diese Methode wird in vielen der folgenden Szenarien verwendet und erstellt einfach ein neues Dokument und importiert den extrahierten Inhalt hinein.
Das folgende Codebeispiel zeigt, wie eine Liste von Knoten erstellt und in ein neues Dokument eingefügt wird.
// 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; | |
} |
Inhalt zwischen Absätzen extrahieren
Dies zeigt, wie Sie mit der obigen Methode Inhalte zwischen bestimmten Absätzen extrahieren. In diesem Fall möchten wir den Text des Briefes extrahieren, der in der ersten Hälfte des Dokuments gefunden wurde. Wir können erkennen, dass dies zwischen dem 7 -ten und dem 11. Absatz liegt.
Der folgende Code führt diese Aufgabe aus. Die entsprechenden Absätze werden mit der GetChild -Methode im Dokument extrahiert und übergeben die angegebenen Indizes. Diese Knoten übergeben wir dann an die Methode ExtractContent und geben an, dass diese in die Extraktion einbezogen werden sollen. Diese Methode gibt den kopierten Inhalt zwischen diesen Knoten zurück, die dann in ein neues Dokument eingefügt werden.
Das folgende Codebeispiel zeigt, wie Sie den Inhalt zwischen bestimmten Absätzen mit der obigen ExtractContent
-Methode extrahieren:
// 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"); |
Extrahieren von Inhalten zwischen verschiedenen Knotentypen
Wir können Inhalte zwischen beliebigen Kombinationen von Block-Level- oder Inline-Knoten extrahieren. In diesem Szenario werden wir den Inhalt zwischen dem ersten Absatz und der Tabelle im zweiten Abschnitt einschließlich extrahieren. Wir erhalten die Markerknoten, indem wir die Methoden Body.FirstParagraph
und GetChild im zweiten Abschnitt des Dokuments aufrufen, um die entsprechenden Absatz- und Tabellenknoten abzurufen. Für eine leichte Variation duplizieren wir stattdessen den Inhalt und fügen ihn unter das Original ein.
Das folgende Codebeispiel zeigt, wie Sie den Inhalt zwischen einem Absatz und einer Tabelle mit der Methode ExtractContent
extrahieren:
// 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"); |
Extrahieren von Inhalten zwischen Absätzen basierend auf dem Stil
Möglicherweise müssen Sie den Inhalt zwischen Absätzen desselben oder verschiedener Stile extrahieren, z. B. zwischen Absätzen, die mit Überschriftenstilen markiert sind. Der folgende Code zeigt, wie dies erreicht werden kann. Es ist ein einfaches Beispiel, das den Inhalt zwischen der ersten Instanz der Stile “Überschrift 1” und “Überschrift 3” extrahiert, ohne auch die Überschriften zu extrahieren. Dazu setzen wir den letzten Parameter auf false, der angibt, dass die Markerknoten nicht enthalten sein sollen.
In einer ordnungsgemäßen Implementierung sollte dies in einer Schleife ausgeführt werden, um Inhalte zwischen allen Absätzen dieser Stile aus dem Dokument zu extrahieren. Der extrahierte Inhalt wird in ein neues Dokument kopiert.
Das folgende Codebeispiel zeigt, wie Inhalte zwischen Absätzen mit bestimmten Stilen mithilfe der ExtractContent
-Methode extrahiert werden:
// 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; | |
} |
Extrahieren von Inhalten zwischen bestimmten Läufen
Sie können auch Inhalte zwischen Inline-Knoten wie Run extrahieren. Runs aus verschiedenen Absätzen können als Marker übergeben werden. Der folgende Code zeigt, wie Sie bestimmten Text zwischen demselben Paragraph -Knoten extrahieren.
Das folgende Codebeispiel zeigt, wie Inhalte zwischen bestimmten Läufen desselben Absatzes mit der Methode ExtractContent extrahiert werden:
// 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; |
Extrahieren von Inhalten mithilfe eines Felds
Um ein Feld als Markierung zu verwenden, sollte der FieldStart
-Knoten übergeben werden. Der letzte Parameter der ExtractContent
-Methode definiert, ob das gesamte Feld eingeschlossen werden soll oder nicht. Extrahieren wir den Inhalt zwischen dem Seriendruckfeld “FullName” und einem Absatz im Dokument. Wir verwenden die MoveToMergeField -Methode der DocumentBuilder -Klasse. Dadurch wird der Knoten FieldStart aus dem Namen des übergebenen Seriendruckfelds zurückgegeben.
In unserem Fall setzen wir den letzten an die ExtractContent -Methode übergebenen Parameter auf false, um das Feld von der Extraktion auszuschließen. Wir werden den extrahierten Inhalt in PDF rendern.
Das folgende Codebeispiel zeigt, wie Sie mit der Methode ExtractContent Inhalte zwischen einem bestimmten Feld und einem Absatz im Dokument extrahieren:
// 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"); |
Inhalte aus einem Lesezeichen extrahieren
In einem Dokument wird der Inhalt, der in einem Lesezeichen definiert ist, durch die Knoten BookmarkStart
und BookmarkEnd gekapselt. Der Inhalt, der zwischen diesen beiden Knoten gefunden wird, bildet das Lesezeichen. Sie können jeden dieser Knoten als beliebige Markierung übergeben, auch als Solche aus verschiedenen Lesezeichen, sofern die Startmarkierung vor der Endmarkierung im Dokument angezeigt wird. Wir werden diesen Inhalt mit dem folgenden Code in ein neues Dokument extrahieren. Die Parameteroption IsInclusive zeigt, wie das Lesezeichen beibehalten oder verworfen wird.
Das folgende Codebeispiel zeigt, wie Sie den Inhalt, auf den ein Lesezeichen verweist, mit der Methode ExtractContent extrahieren:
// 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"); |
Inhalt aus einem Kommentar extrahieren
Ein Kommentar besteht aus den Knoten CommentRangeStart, CommentRangeEnd und Kommentar. Alle diese Knoten sind inline. Die ersten beiden Knoten kapseln den Inhalt des Dokuments ein, auf den der Kommentar verweist, wie in der Abbildung unten zu sehen ist.
Der Comment -Knoten selbst ist eine InlineStory, die Absätze und Läufe enthalten kann. Es stellt die Nachricht des Kommentars als Kommentarblase im Vorschaufenster dar. Da dieser Knoten inline ist und von einem Body abstammt, können Sie den Inhalt auch aus dieser Nachricht extrahieren.
Der Kommentar kapselt die Überschrift, den ersten Absatz und die Tabelle im zweiten Abschnitt ein. Extrahieren wir diesen Kommentar in ein neues Dokument. Die Option IsInclusive bestimmt, ob der Kommentar selbst beibehalten oder verworfen wird.
Das folgende Codebeispiel zeigt, wie dies zu tun ist:
// 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"); |
So extrahieren Sie Inhalte mit DocumentVisitor
Verwenden Sie die Klasse DocumentVisitor, um dieses Verwendungsszenario zu implementieren. Diese Klasse entspricht dem bekannten Besucherdesignmuster. Mit DocumentVisitor, können Sie benutzerdefinierte Operationen definieren und ausführen, die eine Aufzählung über den Dokumentbaum erfordern.
DocumentVisitor
Jede DocumentVisitor.VisitXXX-Methode gibt einen VisitorAction-Wert zurück, der die Aufzählung von Knoten steuert. Sie können entweder anfordern, die Aufzählung fortzusetzen, den aktuellen Knoten zu überspringen (aber die Aufzählung fortzusetzen) oder die Aufzählung von Knoten zu stoppen.
Dies sind die Schritte, die Sie ausführen sollten, um verschiedene Teile eines Dokuments programmgesteuert zu bestimmen und zu extrahieren:
- Erstellen Sie eine von DocumentVisitor abgeleitete Klasse
- Überschreiben und Bereitstellen von Implementierungen für einige oder alle DocumentVisitor.VisitXXX -Methoden, um einige benutzerdefinierte Vorgänge auszuführen
- Rufen Sie
Node.Accept
auf dem Knoten auf, von dem aus Sie die Aufzählung starten möchten. Wenn Sie beispielsweise das gesamte Dokument auflisten möchten, verwenden SieDocument.Accept
DocumentVisitor
Dieses Beispiel zeigt, wie Sie das Besuchermuster verwenden, um dem Aspose.Words-Objektmodell neue Operationen hinzuzufügen. In diesem Fall erstellen wir einen einfachen Dokumentenkonverter in ein Textformat:
// 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); | |
} | |
} | |
}; |
So extrahieren Sie nur Text
Die Möglichkeiten zum Abrufen von Text aus dem Dokument sind:
- Verwenden Sie Document.Save mit SaveFormat.Text, um als Klartext in einer Datei oder einem Stream zu speichern
- Verwenden Sie Node.ToString und übergeben Sie den Parameter SaveFormat.Text. Intern ruft dies das Speichern als Text in einen Speicherstrom auf und gibt die resultierende Zeichenfolge zurück
- Verwenden Sie Node.GetText, um Text mit allen Microsoft Word Steuerzeichen einschließlich Feldcodes abzurufen
- Implementieren Sie eine benutzerdefinierte DocumentVisitor, um eine benutzerdefinierte Extraktion durchzuführen
Verwenden von Node.GetText
und Node.ToString
Ein Word-Dokument kann Steuerzeichen enthalten, die spezielle Elemente wie Feld, Zellende, Abschnittsende usw. kennzeichnen. Die vollständige Liste der möglichen Wortsteuerzeichen ist in der Klasse ControlChar definiert. Die Methode Node.GetText gibt Text mit allen im Knoten vorhandenen Steuerzeichenzeichen zurück.
Der Aufruf von ToString gibt die Klartextdarstellung des Dokuments nur ohne Steuerzeichen zurück.
Das folgende Codebeispiel zeigt den Unterschied zwischen dem Aufruf der Methoden GetText und ToString auf einem Knoten:
// 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; |
Verwenden von SaveFormat.Text
In diesem Beispiel wird das Dokument wie folgt gespeichert:
- Filtert Feldzeichen und Feldcodes, Form-, Fußnoten-, Endnoten- und Kommentarreferenzen heraus
- Ersetzt das Ende von Absatz ControlChar.Cr -Zeichen durch ControlChar.CrLf -Kombinationen
- Verwendet UTF8 -Codierung
Das folgende Codebeispiel zeigt, wie Sie ein Dokument im Format TXT speichern:
// 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"); |
Bilder aus Formen extrahieren
Möglicherweise müssen Sie Dokumentbilder extrahieren, um einige Aufgaben auszuführen. Mit Aspose.Words können Sie dies auch tun.
Das folgende Codebeispiel zeigt, wie Bilder aus einem Dokument extrahiert werden:
// 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++; | |
} | |
} |