search/mag_sel search/close
Aspose::Words::DocumentVisitor Class Reference

Base class for custom document visitors.

With DocumentVisitor you can define and execute custom operations that require enumeration over the document tree.

For example, Aspose.Words uses DocumentVisitor internally for saving Document in various formats and for other operations like finding fields or bookmarks over a fragment of a document.

To use DocumentVisitor:

  1. Create a class derived from DocumentVisitor.
  2. Override and provide implementations for some or all of the VisitXXX methods to perform some custom operations.
  3. Call Node.Accept on the Node that you want to start the enumeration from.

DocumentVisitor provides default implementations for all of the VisitXXX methods to make it easier to create new document visitors as only the methods required for the particular visitor need to be overridden. It is not necessary to override all of the visitor methods.

For more information see the Visitor design pattern.

Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

#include <Aspose.Words.Cpp/DocumentVisitor.h>

+ Inheritance diagram for Aspose::Words::DocumentVisitor:

Public Member Functions

virtual const TypeInfoGetType () const override
 
virtual bool Is (const TypeInfo &target) const override
 
virtual VisitorAction VisitAbsolutePositionTab (SharedPtr< AbsolutePositionTab > tab)
 Called when a AbsolutePositionTab node is encountered in the document. More...
 
virtual VisitorAction VisitBodyEnd (SharedPtr< Body > body)
 Called when enumeration of the main text story in a section has ended. More...
 
virtual VisitorAction VisitBodyStart (SharedPtr< Body > body)
 Called when enumeration of the main text story in a section has started. More...
 
virtual VisitorAction VisitBookmarkEnd (SharedPtr< BookmarkEnd > bookmarkEnd)
 Called when an end of a bookmark is encountered in the document. More...
 
virtual VisitorAction VisitBookmarkStart (SharedPtr< BookmarkStart > bookmarkStart)
 Called when a start of a bookmark is encountered in the document. More...
 
virtual VisitorAction VisitBuildingBlockEnd (SharedPtr< BuildingBlock > block)
 Called when enumeration of a building block has ended. More...
 
virtual VisitorAction VisitBuildingBlockStart (SharedPtr< BuildingBlock > block)
 Called when enumeration of a building block has started. More...
 
virtual VisitorAction VisitCellEnd (SharedPtr< Cell > cell)
 Called when enumeration of a table cell has ended. More...
 
virtual VisitorAction VisitCellStart (SharedPtr< Cell > cell)
 Called when enumeration of a table cell has started. More...
 
virtual VisitorAction VisitCommentEnd (SharedPtr< Comment > comment)
 Called when enumeration of a comment text has ended. More...
 
virtual VisitorAction VisitCommentRangeEnd (SharedPtr< CommentRangeEnd > commentRangeEnd)
 Called when the end of a commented range of text is encountered. More...
 
virtual VisitorAction VisitCommentRangeStart (SharedPtr< CommentRangeStart > commentRangeStart)
 Called when the start of a commented range of text is encountered. More...
 
virtual VisitorAction VisitCommentStart (SharedPtr< Comment > comment)
 Called when enumeration of a comment text has started. More...
 
virtual VisitorAction VisitDocumentEnd (SharedPtr< Document > doc)
 Called when enumeration of the document has finished. More...
 
virtual VisitorAction VisitDocumentStart (SharedPtr< Document > doc)
 Called when enumeration of the document has started. More...
 
virtual VisitorAction VisitEditableRangeEnd (SharedPtr< EditableRangeEnd > editableRangeEnd)
 Called when an end of an editable range is encountered in the document. More...
 
virtual VisitorAction VisitEditableRangeStart (SharedPtr< EditableRangeStart > editableRangeStart)
 Called when a start of an editable range is encountered in the document. More...
 
virtual VisitorAction VisitFieldEnd (SharedPtr< FieldEnd > fieldEnd)
 Called when a field ends in the document. More...
 
virtual VisitorAction VisitFieldSeparator (SharedPtr< FieldSeparator > fieldSeparator)
 Called when a field separator is encountered in the document. More...
 
virtual VisitorAction VisitFieldStart (SharedPtr< FieldStart > fieldStart)
 Called when a field starts in the document. More...
 
virtual VisitorAction VisitFootnoteEnd (SharedPtr< Footnote > footnote)
 Called when enumeration of a footnote or endnote text has ended. More...
 
virtual VisitorAction VisitFootnoteStart (SharedPtr< Footnote > footnote)
 Called when enumeration of a footnote or endnote text has started. More...
 
virtual VisitorAction VisitFormField (SharedPtr< FormField > formField)
 Called when a form field is encountered in the document. More...
 
virtual VisitorAction VisitGlossaryDocumentEnd (SharedPtr< GlossaryDocument > glossary)
 Called when enumeration of a glossary document has ended. More...
 
virtual VisitorAction VisitGlossaryDocumentStart (SharedPtr< GlossaryDocument > glossary)
 Called when enumeration of a glossary document has started. More...
 
virtual VisitorAction VisitGroupShapeEnd (SharedPtr< GroupShape > groupShape)
 Called when enumeration of a group shape has ended. More...
 
virtual VisitorAction VisitGroupShapeStart (SharedPtr< GroupShape > groupShape)
 Called when enumeration of a group shape has started. More...
 
virtual VisitorAction VisitHeaderFooterEnd (SharedPtr< HeaderFooter > headerFooter)
 Called when enumeration of a header or footer in a section has ended. More...
 
virtual VisitorAction VisitHeaderFooterStart (SharedPtr< HeaderFooter > headerFooter)
 Called when enumeration of a header or footer in a section has started. More...
 
virtual VisitorAction VisitOfficeMathEnd (SharedPtr< OfficeMath > officeMath)
 Called when enumeration of a Office Math object has ended. More...
 
virtual VisitorAction VisitOfficeMathStart (SharedPtr< OfficeMath > officeMath)
 Called when enumeration of a Office Math object has started. More...
 
virtual VisitorAction VisitParagraphEnd (SharedPtr< Paragraph > paragraph)
 Called when enumeration of a paragraph has ended. More...
 
virtual VisitorAction VisitParagraphStart (SharedPtr< Paragraph > paragraph)
 Called when enumeration of a paragraph has started. More...
 
virtual VisitorAction VisitRowEnd (SharedPtr< Row > row)
 Called when enumeration of a table row has ended. More...
 
virtual VisitorAction VisitRowStart (SharedPtr< Row > row)
 Called when enumeration of a table row has started. More...
 
virtual VisitorAction VisitRun (SharedPtr< Run > run)
 Called when a run of text in the is encountered. More...
 
virtual VisitorAction VisitSectionEnd (SharedPtr< Section > section)
 Called when enumeration of a section has ended. More...
 
virtual VisitorAction VisitSectionStart (SharedPtr< Section > section)
 Called when enumeration of a section has started. More...
 
virtual VisitorAction VisitShapeEnd (SharedPtr< Shape > shape)
 Called when enumeration of a shape has ended. More...
 
virtual VisitorAction VisitShapeStart (SharedPtr< Shape > shape)
 Called when enumeration of a shape has started. More...
 
virtual VisitorAction VisitSmartTagEnd (SharedPtr< SmartTag > smartTag)
 Called when enumeration of a smart tag has ended. More...
 
virtual VisitorAction VisitSmartTagStart (SharedPtr< SmartTag > smartTag)
 Called when enumeration of a smart tag has started. More...
 
virtual VisitorAction VisitSpecialChar (SharedPtr< SpecialChar > specialChar)
 Called when a SpecialChar node is encountered in the document. More...
 
virtual VisitorAction VisitStructuredDocumentTagEnd (SharedPtr< StructuredDocumentTag > sdt)
 Called when enumeration of a structured document tag has ended. More...
 
virtual VisitorAction VisitStructuredDocumentTagRangeEnd (SharedPtr< StructuredDocumentTagRangeEnd > sdtRangeEnd)
 
virtual VisitorAction VisitStructuredDocumentTagRangeStart (SharedPtr< StructuredDocumentTagRangeStart > sdtRangeStart)
 
virtual VisitorAction VisitStructuredDocumentTagStart (SharedPtr< StructuredDocumentTag > sdt)
 Called when enumeration of a structured document tag has started. More...
 
virtual VisitorAction VisitSubDocument (SharedPtr< SubDocument > subDocument)
 Called when a subDocument is encountered. More...
 
virtual VisitorAction VisitTableEnd (SharedPtr< Table > table)
 Called when enumeration of a table has ended. More...
 
virtual VisitorAction VisitTableStart (SharedPtr< Table > table)
 Called when enumeration of a table has started. More...
 

Static Public Member Functions

static const TypeInfoType ()
 

Member Function Documentation

◆ GetType()

virtual const System::TypeInfo& Aspose::Words::DocumentVisitor::GetType ( ) const
overridevirtual

Reimplemented from System::Object.

◆ Is()

virtual bool Aspose::Words::DocumentVisitor::Is ( const System::TypeInfo target) const
overridevirtual

Reimplemented from System::Object.

◆ Type()

static const System::TypeInfo& Aspose::Words::DocumentVisitor::Type ( )
static

◆ VisitAbsolutePositionTab()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitAbsolutePositionTab ( System::SharedPtr< Aspose::Words::AbsolutePositionTab tab)
virtual

Called when a AbsolutePositionTab node is encountered in the document.

Parameters
tabThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to process absolute position tab characters with a document visitor.

void DocumentToTxt()
{
auto doc = MakeObject<Document>(MyDir + u"Absolute position tab.docx");
// Extract the text contents of our document by accepting this custom document visitor.
auto myDocTextExtractor = MakeObject<ExAbsolutePositionTab::DocTextExtractor>();
doc->get_FirstSection()->get_Body()->Accept(myDocTextExtractor);
// The absolute position tab, which has no equivalent in string form, has been explicitly converted to a tab character.
ASSERT_EQ(u"Before AbsolutePositionTab\tAfter AbsolutePositionTab", myDocTextExtractor->GetText());
// An AbsolutePositionTab can accept a DocumentVisitor by itself too.
auto absPositionTab =
System::DynamicCast<AbsolutePositionTab>(doc->get_FirstSection()->get_Body()->get_FirstParagraph()->GetChild(NodeType::SpecialChar, 0, true));
myDocTextExtractor = MakeObject<ExAbsolutePositionTab::DocTextExtractor>();
absPositionTab->Accept(myDocTextExtractor);
ASSERT_EQ(u"\t", myDocTextExtractor->GetText());
}
class DocTextExtractor : public DocumentVisitor
{
public:
DocTextExtractor()
{
mBuilder = MakeObject<System::Text::StringBuilder>();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
AppendText(run->get_Text());
}
VisitorAction VisitAbsolutePositionTab(SharedPtr<AbsolutePositionTab> tab) override
{
mBuilder->Append(u"\t");
}
String GetText()
{
return mBuilder->ToString();
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
void AppendText(String text)
{
mBuilder->Append(text);
}
};

◆ VisitBodyEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBodyEnd ( System::SharedPtr< Aspose::Words::Body body)
virtual

Called when enumeration of the main text story in a section has ended.

Parameters
bodyThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitBodyStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBodyStart ( System::SharedPtr< Aspose::Words::Body body)
virtual

Called when enumeration of the main text story in a section has started.

Parameters
bodyThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitBookmarkEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBookmarkEnd ( System::SharedPtr< Aspose::Words::BookmarkEnd bookmarkEnd)
virtual

Called when an end of a bookmark is encountered in the document.

Parameters
bookmarkEndThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to add bookmarks and update their contents.

void CreateUpdateAndPrintBookmarks()
{
// Create a document with three bookmarks, then use a custom document visitor implementation to print their contents.
SharedPtr<Document> doc = CreateDocumentWithBookmarks(3);
SharedPtr<BookmarkCollection> bookmarks = doc->get_Range()->get_Bookmarks();
PrintAllBookmarkInfo(bookmarks);
// Bookmarks can be accessed in the bookmark collection by index or name, and their names can be updated.
bookmarks->idx_get(0)->set_Name(String::Format(u"{0}_NewName", bookmarks->idx_get(0)->get_Name()));
bookmarks->idx_get(u"MyBookmark_2")->set_Text(String::Format(u"Updated text contents of {0}", bookmarks->idx_get(1)->get_Name()));
// Print all bookmarks again to see updated values.
PrintAllBookmarkInfo(bookmarks);
}
static SharedPtr<Document> CreateDocumentWithBookmarks(int numberOfBookmarks)
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
for (int i = 1; i <= numberOfBookmarks; i++)
{
String bookmarkName = String(u"MyBookmark_") + i;
builder->Write(u"Text before bookmark.");
builder->StartBookmark(bookmarkName);
builder->Write(String::Format(u"Text inside {0}.", bookmarkName));
builder->EndBookmark(bookmarkName);
builder->Writeln(u"Text after bookmark.");
}
return doc;
}
static void PrintAllBookmarkInfo(SharedPtr<BookmarkCollection> bookmarks)
{
auto bookmarkVisitor = MakeObject<ExBookmarks::BookmarkInfoPrinter>();
// Get each bookmark in the collection to accept a visitor that will print its contents.
{
SharedPtr<System::Collections::Generic::IEnumerator<SharedPtr<Bookmark>>> enumerator = bookmarks->GetEnumerator();
while (enumerator->MoveNext())
{
SharedPtr<Bookmark> currentBookmark = enumerator->get_Current();
if (currentBookmark != nullptr)
{
currentBookmark->get_BookmarkStart()->Accept(bookmarkVisitor);
currentBookmark->get_BookmarkEnd()->Accept(bookmarkVisitor);
std::cout << currentBookmark->get_BookmarkStart()->GetText() << std::endl;
}
}
}
}
class BookmarkInfoPrinter : public DocumentVisitor
{
public:
VisitorAction VisitBookmarkStart(SharedPtr<BookmarkStart> bookmarkStart) override
{
std::cout << "BookmarkStart name: \"" << bookmarkStart->get_Name() << "\", Contents: \"" << bookmarkStart->get_Bookmark()->get_Text() << "\""
<< std::endl;
}
VisitorAction VisitBookmarkEnd(SharedPtr<BookmarkEnd> bookmarkEnd) override
{
std::cout << "BookmarkEnd name: \"" << bookmarkEnd->get_Name() << "\"" << std::endl;
}
};

◆ VisitBookmarkStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBookmarkStart ( System::SharedPtr< Aspose::Words::BookmarkStart bookmarkStart)
virtual

Called when a start of a bookmark is encountered in the document.

Parameters
bookmarkStartThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to add bookmarks and update their contents.

void CreateUpdateAndPrintBookmarks()
{
// Create a document with three bookmarks, then use a custom document visitor implementation to print their contents.
SharedPtr<Document> doc = CreateDocumentWithBookmarks(3);
SharedPtr<BookmarkCollection> bookmarks = doc->get_Range()->get_Bookmarks();
PrintAllBookmarkInfo(bookmarks);
// Bookmarks can be accessed in the bookmark collection by index or name, and their names can be updated.
bookmarks->idx_get(0)->set_Name(String::Format(u"{0}_NewName", bookmarks->idx_get(0)->get_Name()));
bookmarks->idx_get(u"MyBookmark_2")->set_Text(String::Format(u"Updated text contents of {0}", bookmarks->idx_get(1)->get_Name()));
// Print all bookmarks again to see updated values.
PrintAllBookmarkInfo(bookmarks);
}
static SharedPtr<Document> CreateDocumentWithBookmarks(int numberOfBookmarks)
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
for (int i = 1; i <= numberOfBookmarks; i++)
{
String bookmarkName = String(u"MyBookmark_") + i;
builder->Write(u"Text before bookmark.");
builder->StartBookmark(bookmarkName);
builder->Write(String::Format(u"Text inside {0}.", bookmarkName));
builder->EndBookmark(bookmarkName);
builder->Writeln(u"Text after bookmark.");
}
return doc;
}
static void PrintAllBookmarkInfo(SharedPtr<BookmarkCollection> bookmarks)
{
auto bookmarkVisitor = MakeObject<ExBookmarks::BookmarkInfoPrinter>();
// Get each bookmark in the collection to accept a visitor that will print its contents.
{
SharedPtr<System::Collections::Generic::IEnumerator<SharedPtr<Bookmark>>> enumerator = bookmarks->GetEnumerator();
while (enumerator->MoveNext())
{
SharedPtr<Bookmark> currentBookmark = enumerator->get_Current();
if (currentBookmark != nullptr)
{
currentBookmark->get_BookmarkStart()->Accept(bookmarkVisitor);
currentBookmark->get_BookmarkEnd()->Accept(bookmarkVisitor);
std::cout << currentBookmark->get_BookmarkStart()->GetText() << std::endl;
}
}
}
}
class BookmarkInfoPrinter : public DocumentVisitor
{
public:
VisitorAction VisitBookmarkStart(SharedPtr<BookmarkStart> bookmarkStart) override
{
std::cout << "BookmarkStart name: \"" << bookmarkStart->get_Name() << "\", Contents: \"" << bookmarkStart->get_Bookmark()->get_Text() << "\""
<< std::endl;
}
VisitorAction VisitBookmarkEnd(SharedPtr<BookmarkEnd> bookmarkEnd) override
{
std::cout << "BookmarkEnd name: \"" << bookmarkEnd->get_Name() << "\"" << std::endl;
}
};

◆ VisitBuildingBlockEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBuildingBlockEnd ( System::SharedPtr< Aspose::Words::BuildingBlocks::BuildingBlock block)
virtual

Called when enumeration of a building block has ended.

Note: A building block node and its children are not visited when you execute a Visitor over a Document. If you want to execute a Visitor over a building block, you need to execute the visitor over GlossaryDocument or call Accept().

Parameters
blockThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows ways of accessing building blocks in a glossary document.

void GlossaryDocument_()
{
auto doc = MakeObject<Document>();
auto glossaryDoc = MakeObject<GlossaryDocument>();
for (int i = 1; i <= 5; ++i)
{
auto block = MakeObject<BuildingBlock>(glossaryDoc);
block->set_Name(String(u"Block ") + System::Convert::ToString(i));
glossaryDoc->AppendChild(block);
}
ASSERT_EQ(5, glossaryDoc->get_BuildingBlocks()->get_Count());
doc->set_GlossaryDocument(glossaryDoc);
// There are various ways of accessing building blocks.
// 1 - Get the first/last building blocks in the collection:
ASSERT_EQ(u"Block 1", glossaryDoc->get_FirstBuildingBlock()->get_Name());
ASSERT_EQ(u"Block 5", glossaryDoc->get_LastBuildingBlock()->get_Name());
// 2 - Get a building block by index:
ASSERT_EQ(u"Block 2", glossaryDoc->get_BuildingBlocks()->idx_get(1)->get_Name());
ASSERT_EQ(u"Block 3", glossaryDoc->get_BuildingBlocks()->ToArray()->idx_get(2)->get_Name());
// 3 - Get the first building block that matches a gallery, name and category:
ASSERT_EQ(u"Block 4", glossaryDoc->GetBuildingBlock(BuildingBlockGallery::All, u"(Empty Category)", u"Block 4")->get_Name());
// We will do that using a custom visitor,
// which will give every BuildingBlock in the GlossaryDocument a unique GUID
auto visitor = MakeObject<ExBuildingBlocks::GlossaryDocVisitor>();
glossaryDoc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// In Microsoft Word, we can access the building blocks via "Insert" -> "Quick Parts" -> "Building Blocks Organizer".
doc->Save(ArtifactsDir + u"BuildingBlocks.GlossaryDocument.dotx");
}
class GlossaryDocVisitor : public DocumentVisitor
{
public:
GlossaryDocVisitor()
{
mBlocksByGuid = MakeObject<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>>();
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> GetDictionary()
{
return mBlocksByGuid;
}
VisitorAction VisitGlossaryDocumentStart(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Glossary document found!");
}
VisitorAction VisitGlossaryDocumentEnd(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Reached end of glossary!");
mBuilder->AppendLine(String(u"BuildingBlocks found: ") + mBlocksByGuid->get_Count());
}
VisitorAction VisitBuildingBlockStart(SharedPtr<BuildingBlock> block) override
{
block->set_Guid(System::Guid::NewGuid());
mBlocksByGuid->Add(block->get_Guid(), block);
}
VisitorAction VisitBuildingBlockEnd(SharedPtr<BuildingBlock> block) override
{
mBuilder->AppendLine(String(u"\tVisited block \"") + block->get_Name() + u"\"");
mBuilder->AppendLine(String(u"\t Type: ") + System::ObjectExt::ToString(block->get_Type()));
mBuilder->AppendLine(String(u"\t Gallery: ") + System::ObjectExt::ToString(block->get_Gallery()));
mBuilder->AppendLine(String(u"\t Behavior: ") + System::ObjectExt::ToString(block->get_Behavior()));
mBuilder->AppendLine(String(u"\t Description: ") + block->get_Description());
}
private:
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> mBlocksByGuid;
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitBuildingBlockStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitBuildingBlockStart ( System::SharedPtr< Aspose::Words::BuildingBlocks::BuildingBlock block)
virtual

Called when enumeration of a building block has started.

Note: A building block node and its children are not visited when you execute a Visitor over a Document. If you want to execute a Visitor over a building block, you need to execute the visitor over GlossaryDocument or call Accept().

Parameters
blockThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows ways of accessing building blocks in a glossary document.

void GlossaryDocument_()
{
auto doc = MakeObject<Document>();
auto glossaryDoc = MakeObject<GlossaryDocument>();
for (int i = 1; i <= 5; ++i)
{
auto block = MakeObject<BuildingBlock>(glossaryDoc);
block->set_Name(String(u"Block ") + System::Convert::ToString(i));
glossaryDoc->AppendChild(block);
}
ASSERT_EQ(5, glossaryDoc->get_BuildingBlocks()->get_Count());
doc->set_GlossaryDocument(glossaryDoc);
// There are various ways of accessing building blocks.
// 1 - Get the first/last building blocks in the collection:
ASSERT_EQ(u"Block 1", glossaryDoc->get_FirstBuildingBlock()->get_Name());
ASSERT_EQ(u"Block 5", glossaryDoc->get_LastBuildingBlock()->get_Name());
// 2 - Get a building block by index:
ASSERT_EQ(u"Block 2", glossaryDoc->get_BuildingBlocks()->idx_get(1)->get_Name());
ASSERT_EQ(u"Block 3", glossaryDoc->get_BuildingBlocks()->ToArray()->idx_get(2)->get_Name());
// 3 - Get the first building block that matches a gallery, name and category:
ASSERT_EQ(u"Block 4", glossaryDoc->GetBuildingBlock(BuildingBlockGallery::All, u"(Empty Category)", u"Block 4")->get_Name());
// We will do that using a custom visitor,
// which will give every BuildingBlock in the GlossaryDocument a unique GUID
auto visitor = MakeObject<ExBuildingBlocks::GlossaryDocVisitor>();
glossaryDoc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// In Microsoft Word, we can access the building blocks via "Insert" -> "Quick Parts" -> "Building Blocks Organizer".
doc->Save(ArtifactsDir + u"BuildingBlocks.GlossaryDocument.dotx");
}
class GlossaryDocVisitor : public DocumentVisitor
{
public:
GlossaryDocVisitor()
{
mBlocksByGuid = MakeObject<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>>();
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> GetDictionary()
{
return mBlocksByGuid;
}
VisitorAction VisitGlossaryDocumentStart(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Glossary document found!");
}
VisitorAction VisitGlossaryDocumentEnd(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Reached end of glossary!");
mBuilder->AppendLine(String(u"BuildingBlocks found: ") + mBlocksByGuid->get_Count());
}
VisitorAction VisitBuildingBlockStart(SharedPtr<BuildingBlock> block) override
{
block->set_Guid(System::Guid::NewGuid());
mBlocksByGuid->Add(block->get_Guid(), block);
}
VisitorAction VisitBuildingBlockEnd(SharedPtr<BuildingBlock> block) override
{
mBuilder->AppendLine(String(u"\tVisited block \"") + block->get_Name() + u"\"");
mBuilder->AppendLine(String(u"\t Type: ") + System::ObjectExt::ToString(block->get_Type()));
mBuilder->AppendLine(String(u"\t Gallery: ") + System::ObjectExt::ToString(block->get_Gallery()));
mBuilder->AppendLine(String(u"\t Behavior: ") + System::ObjectExt::ToString(block->get_Behavior()));
mBuilder->AppendLine(String(u"\t Description: ") + block->get_Description());
}
private:
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> mBlocksByGuid;
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitCellEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCellEnd ( System::SharedPtr< Aspose::Words::Tables::Cell cell)
virtual

Called when enumeration of a table cell has ended.

Parameters
cellThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitCellStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCellStart ( System::SharedPtr< Aspose::Words::Tables::Cell cell)
virtual

Called when enumeration of a table cell has started.

Parameters
cellThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};

◆ VisitCommentEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCommentEnd ( System::SharedPtr< Aspose::Words::Comment comment)
virtual

Called when enumeration of a comment text has ended.

Parameters
commentThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every comment and comment range in a document.

void CommentsToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::CommentStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class CommentStructurePrinter : public DocumentVisitor
{
public:
CommentStructurePrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment range end]");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitCommentRangeEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCommentRangeEnd ( System::SharedPtr< Aspose::Words::CommentRangeEnd commentRangeEnd)
virtual

Called when the end of a commented range of text is encountered.

Parameters
commentRangeEndThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every comment and comment range in a document.

void CommentsToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::CommentStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class CommentStructurePrinter : public DocumentVisitor
{
public:
CommentStructurePrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment range end]");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitCommentRangeStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCommentRangeStart ( System::SharedPtr< Aspose::Words::CommentRangeStart commentRangeStart)
virtual

Called when the start of a commented range of text is encountered.

Parameters
commentRangeStartThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every comment and comment range in a document.

void CommentsToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::CommentStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class CommentStructurePrinter : public DocumentVisitor
{
public:
CommentStructurePrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment range end]");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitCommentStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitCommentStart ( System::SharedPtr< Aspose::Words::Comment comment)
virtual

Called when enumeration of a comment text has started.

Parameters
commentThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every comment and comment range in a document.

void CommentsToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::CommentStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class CommentStructurePrinter : public DocumentVisitor
{
public:
CommentStructurePrinter() : mVisitorIsInsideComment(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideComment = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideComment)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitCommentRangeStart(SharedPtr<CommentRangeStart> commentRangeStart) override
{
IndentAndAppendLine(String(u"[Comment range start] ID: ") + commentRangeStart->get_Id());
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentRangeEnd(SharedPtr<CommentRangeEnd> commentRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment range end]");
mVisitorIsInsideComment = false;
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
IndentAndAppendLine(
String::Format(u"[Comment start] For comment range ID {0}, By {1} on {2}", comment->get_Id(), comment->get_Author(), comment->get_DateTime()));
mDocTraversalDepth++;
mVisitorIsInsideComment = true;
}
VisitorAction VisitCommentEnd(SharedPtr<Comment> comment) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Comment end]");
mVisitorIsInsideComment = false;
}
private:
bool mVisitorIsInsideComment;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitDocumentEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitDocumentEnd ( System::SharedPtr< Aspose::Words::Document doc)
virtual

Called when enumeration of the document has finished.

Parameters
docThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitDocumentStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitDocumentStart ( System::SharedPtr< Aspose::Words::Document doc)
virtual

Called when enumeration of the document has started.

Parameters
docThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitEditableRangeEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitEditableRangeEnd ( System::SharedPtr< Aspose::Words::EditableRangeEnd editableRangeEnd)
virtual

Called when an end of an editable range is encountered in the document.

Parameters
editableRangeEndThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every editable range in a document.

void EditableRangeToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::EditableRangeStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class EditableRangeStructurePrinter : public DocumentVisitor
{
public:
EditableRangeStructurePrinter() : mVisitorIsInsideEditableRange(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideEditableRange = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
// We want to print the contents of runs, but only if they are inside shapes, as they would be in the case of text boxes
if (mVisitorIsInsideEditableRange)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitEditableRangeStart(SharedPtr<EditableRangeStart> editableRangeStart) override
{
IndentAndAppendLine(String(u"[EditableRange start] ID: ") + editableRangeStart->get_Id() + u" Owner: " +
editableRangeStart->get_EditableRange()->get_SingleUser());
mDocTraversalDepth++;
mVisitorIsInsideEditableRange = true;
}
VisitorAction VisitEditableRangeEnd(SharedPtr<EditableRangeEnd> editableRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[EditableRange end]");
mVisitorIsInsideEditableRange = false;
}
private:
bool mVisitorIsInsideEditableRange;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitEditableRangeStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitEditableRangeStart ( System::SharedPtr< Aspose::Words::EditableRangeStart editableRangeStart)
virtual

Called when a start of an editable range is encountered in the document.

Parameters
editableRangeStartThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every editable range in a document.

void EditableRangeToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::EditableRangeStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class EditableRangeStructurePrinter : public DocumentVisitor
{
public:
EditableRangeStructurePrinter() : mVisitorIsInsideEditableRange(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideEditableRange = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
// We want to print the contents of runs, but only if they are inside shapes, as they would be in the case of text boxes
if (mVisitorIsInsideEditableRange)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitEditableRangeStart(SharedPtr<EditableRangeStart> editableRangeStart) override
{
IndentAndAppendLine(String(u"[EditableRange start] ID: ") + editableRangeStart->get_Id() + u" Owner: " +
editableRangeStart->get_EditableRange()->get_SingleUser());
mDocTraversalDepth++;
mVisitorIsInsideEditableRange = true;
}
VisitorAction VisitEditableRangeEnd(SharedPtr<EditableRangeEnd> editableRangeEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[EditableRange end]");
mVisitorIsInsideEditableRange = false;
}
private:
bool mVisitorIsInsideEditableRange;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitFieldEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFieldEnd ( System::SharedPtr< Aspose::Words::Fields::FieldEnd fieldEnd)
virtual

Called when a field ends in the document.

For more info see VisitFieldStart()

Parameters
fieldEndThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every field in a document.

void FieldToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::FieldStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class FieldStructurePrinter : public DocumentVisitor
{
public:
FieldStructurePrinter() : mVisitorIsInsideField(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideField = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideField)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
IndentAndAppendLine(String(u"[Field start] FieldType: ") + System::ObjectExt::ToString(fieldStart->get_FieldType()));
mDocTraversalDepth++;
mVisitorIsInsideField = true;
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Field end]");
mVisitorIsInsideField = false;
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
IndentAndAppendLine(u"[FieldSeparator]");
}
private:
bool mVisitorIsInsideField;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitFieldSeparator()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFieldSeparator ( System::SharedPtr< Aspose::Words::Fields::FieldSeparator fieldSeparator)
virtual

Called when a field separator is encountered in the document.

The field separator separates field code from field value in the document. Note that some fields have only field code and do not have field separator and field value.

For more info see VisitFieldStart()

Parameters
fieldSeparatorThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every field in a document.

void FieldToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::FieldStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class FieldStructurePrinter : public DocumentVisitor
{
public:
FieldStructurePrinter() : mVisitorIsInsideField(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideField = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideField)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
IndentAndAppendLine(String(u"[Field start] FieldType: ") + System::ObjectExt::ToString(fieldStart->get_FieldType()));
mDocTraversalDepth++;
mVisitorIsInsideField = true;
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Field end]");
mVisitorIsInsideField = false;
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
IndentAndAppendLine(u"[FieldSeparator]");
}
private:
bool mVisitorIsInsideField;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitFieldStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFieldStart ( System::SharedPtr< Aspose::Words::Fields::FieldStart fieldStart)
virtual

Called when a field starts in the document.

A field in a Word Word document consists of a field code and field value.

For example, a field that displays a page number can be represented as follows:

[FieldStart]PAGE[FieldSeparator]98[FieldEnd]

The field separator separates field code from field value in the document. Note that some fields have only field code and do not have field separator and field value.

Fields can be nested.

Parameters
fieldStartThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every field in a document.

void FieldToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::FieldStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class FieldStructurePrinter : public DocumentVisitor
{
public:
FieldStructurePrinter() : mVisitorIsInsideField(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideField = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideField)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
IndentAndAppendLine(String(u"[Field start] FieldType: ") + System::ObjectExt::ToString(fieldStart->get_FieldType()));
mDocTraversalDepth++;
mVisitorIsInsideField = true;
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Field end]");
mVisitorIsInsideField = false;
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
IndentAndAppendLine(u"[FieldSeparator]");
}
private:
bool mVisitorIsInsideField;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitFootnoteEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFootnoteEnd ( System::SharedPtr< Aspose::Words::Notes::Footnote footnote)
virtual

Called when enumeration of a footnote or endnote text has ended.

Parameters
footnoteThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every footnote in a document.

void FootnoteToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::FootnoteStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class FootnoteStructurePrinter : public DocumentVisitor
{
public:
FootnoteStructurePrinter() : mVisitorIsInsideFootnote(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideFootnote = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
IndentAndAppendLine(String(u"[Footnote start] Type: ") + System::ObjectExt::ToString(footnote->get_FootnoteType()));
mDocTraversalDepth++;
mVisitorIsInsideFootnote = true;
}
VisitorAction VisitFootnoteEnd(SharedPtr<Footnote> footnote) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Footnote end]");
mVisitorIsInsideFootnote = false;
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideFootnote)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
private:
bool mVisitorIsInsideFootnote;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitFootnoteStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFootnoteStart ( System::SharedPtr< Aspose::Words::Notes::Footnote footnote)
virtual

Called when enumeration of a footnote or endnote text has started.

Parameters
footnoteThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every footnote in a document.

void FootnoteToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::FootnoteStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class FootnoteStructurePrinter : public DocumentVisitor
{
public:
FootnoteStructurePrinter() : mVisitorIsInsideFootnote(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideFootnote = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
IndentAndAppendLine(String(u"[Footnote start] Type: ") + System::ObjectExt::ToString(footnote->get_FootnoteType()));
mDocTraversalDepth++;
mVisitorIsInsideFootnote = true;
}
VisitorAction VisitFootnoteEnd(SharedPtr<Footnote> footnote) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Footnote end]");
mVisitorIsInsideFootnote = false;
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideFootnote)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
private:
bool mVisitorIsInsideFootnote;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitFormField()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitFormField ( System::SharedPtr< Aspose::Words::Fields::FormField formField)
virtual

Called when a form field is encountered in the document.

Parameters
formFieldThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitGlossaryDocumentEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitGlossaryDocumentEnd ( System::SharedPtr< Aspose::Words::BuildingBlocks::GlossaryDocument glossary)
virtual

Called when enumeration of a glossary document has ended.

Note: A glossary document node and its children are not visited when you execute a Visitor over a Document. If you want to execute a Visitor over a glossary document, you need to call Accept().

Parameters
glossaryThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows ways of accessing building blocks in a glossary document.

void GlossaryDocument_()
{
auto doc = MakeObject<Document>();
auto glossaryDoc = MakeObject<GlossaryDocument>();
for (int i = 1; i <= 5; ++i)
{
auto block = MakeObject<BuildingBlock>(glossaryDoc);
block->set_Name(String(u"Block ") + System::Convert::ToString(i));
glossaryDoc->AppendChild(block);
}
ASSERT_EQ(5, glossaryDoc->get_BuildingBlocks()->get_Count());
doc->set_GlossaryDocument(glossaryDoc);
// There are various ways of accessing building blocks.
// 1 - Get the first/last building blocks in the collection:
ASSERT_EQ(u"Block 1", glossaryDoc->get_FirstBuildingBlock()->get_Name());
ASSERT_EQ(u"Block 5", glossaryDoc->get_LastBuildingBlock()->get_Name());
// 2 - Get a building block by index:
ASSERT_EQ(u"Block 2", glossaryDoc->get_BuildingBlocks()->idx_get(1)->get_Name());
ASSERT_EQ(u"Block 3", glossaryDoc->get_BuildingBlocks()->ToArray()->idx_get(2)->get_Name());
// 3 - Get the first building block that matches a gallery, name and category:
ASSERT_EQ(u"Block 4", glossaryDoc->GetBuildingBlock(BuildingBlockGallery::All, u"(Empty Category)", u"Block 4")->get_Name());
// We will do that using a custom visitor,
// which will give every BuildingBlock in the GlossaryDocument a unique GUID
auto visitor = MakeObject<ExBuildingBlocks::GlossaryDocVisitor>();
glossaryDoc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// In Microsoft Word, we can access the building blocks via "Insert" -> "Quick Parts" -> "Building Blocks Organizer".
doc->Save(ArtifactsDir + u"BuildingBlocks.GlossaryDocument.dotx");
}
class GlossaryDocVisitor : public DocumentVisitor
{
public:
GlossaryDocVisitor()
{
mBlocksByGuid = MakeObject<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>>();
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> GetDictionary()
{
return mBlocksByGuid;
}
VisitorAction VisitGlossaryDocumentStart(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Glossary document found!");
}
VisitorAction VisitGlossaryDocumentEnd(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Reached end of glossary!");
mBuilder->AppendLine(String(u"BuildingBlocks found: ") + mBlocksByGuid->get_Count());
}
VisitorAction VisitBuildingBlockStart(SharedPtr<BuildingBlock> block) override
{
block->set_Guid(System::Guid::NewGuid());
mBlocksByGuid->Add(block->get_Guid(), block);
}
VisitorAction VisitBuildingBlockEnd(SharedPtr<BuildingBlock> block) override
{
mBuilder->AppendLine(String(u"\tVisited block \"") + block->get_Name() + u"\"");
mBuilder->AppendLine(String(u"\t Type: ") + System::ObjectExt::ToString(block->get_Type()));
mBuilder->AppendLine(String(u"\t Gallery: ") + System::ObjectExt::ToString(block->get_Gallery()));
mBuilder->AppendLine(String(u"\t Behavior: ") + System::ObjectExt::ToString(block->get_Behavior()));
mBuilder->AppendLine(String(u"\t Description: ") + block->get_Description());
}
private:
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> mBlocksByGuid;
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitGlossaryDocumentStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitGlossaryDocumentStart ( System::SharedPtr< Aspose::Words::BuildingBlocks::GlossaryDocument glossary)
virtual

Called when enumeration of a glossary document has started.

Note: A glossary document node and its children are not visited when you execute a Visitor over a Document. If you want to execute a Visitor over a glossary document, you need to call Accept().

Parameters
glossaryThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows ways of accessing building blocks in a glossary document.

void GlossaryDocument_()
{
auto doc = MakeObject<Document>();
auto glossaryDoc = MakeObject<GlossaryDocument>();
for (int i = 1; i <= 5; ++i)
{
auto block = MakeObject<BuildingBlock>(glossaryDoc);
block->set_Name(String(u"Block ") + System::Convert::ToString(i));
glossaryDoc->AppendChild(block);
}
ASSERT_EQ(5, glossaryDoc->get_BuildingBlocks()->get_Count());
doc->set_GlossaryDocument(glossaryDoc);
// There are various ways of accessing building blocks.
// 1 - Get the first/last building blocks in the collection:
ASSERT_EQ(u"Block 1", glossaryDoc->get_FirstBuildingBlock()->get_Name());
ASSERT_EQ(u"Block 5", glossaryDoc->get_LastBuildingBlock()->get_Name());
// 2 - Get a building block by index:
ASSERT_EQ(u"Block 2", glossaryDoc->get_BuildingBlocks()->idx_get(1)->get_Name());
ASSERT_EQ(u"Block 3", glossaryDoc->get_BuildingBlocks()->ToArray()->idx_get(2)->get_Name());
// 3 - Get the first building block that matches a gallery, name and category:
ASSERT_EQ(u"Block 4", glossaryDoc->GetBuildingBlock(BuildingBlockGallery::All, u"(Empty Category)", u"Block 4")->get_Name());
// We will do that using a custom visitor,
// which will give every BuildingBlock in the GlossaryDocument a unique GUID
auto visitor = MakeObject<ExBuildingBlocks::GlossaryDocVisitor>();
glossaryDoc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// In Microsoft Word, we can access the building blocks via "Insert" -> "Quick Parts" -> "Building Blocks Organizer".
doc->Save(ArtifactsDir + u"BuildingBlocks.GlossaryDocument.dotx");
}
class GlossaryDocVisitor : public DocumentVisitor
{
public:
GlossaryDocVisitor()
{
mBlocksByGuid = MakeObject<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>>();
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> GetDictionary()
{
return mBlocksByGuid;
}
VisitorAction VisitGlossaryDocumentStart(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Glossary document found!");
}
VisitorAction VisitGlossaryDocumentEnd(SharedPtr<GlossaryDocument> glossary) override
{
mBuilder->AppendLine(u"Reached end of glossary!");
mBuilder->AppendLine(String(u"BuildingBlocks found: ") + mBlocksByGuid->get_Count());
}
VisitorAction VisitBuildingBlockStart(SharedPtr<BuildingBlock> block) override
{
block->set_Guid(System::Guid::NewGuid());
mBlocksByGuid->Add(block->get_Guid(), block);
}
VisitorAction VisitBuildingBlockEnd(SharedPtr<BuildingBlock> block) override
{
mBuilder->AppendLine(String(u"\tVisited block \"") + block->get_Name() + u"\"");
mBuilder->AppendLine(String(u"\t Type: ") + System::ObjectExt::ToString(block->get_Type()));
mBuilder->AppendLine(String(u"\t Gallery: ") + System::ObjectExt::ToString(block->get_Gallery()));
mBuilder->AppendLine(String(u"\t Behavior: ") + System::ObjectExt::ToString(block->get_Behavior()));
mBuilder->AppendLine(String(u"\t Description: ") + block->get_Description());
}
private:
SharedPtr<System::Collections::Generic::Dictionary<System::Guid, SharedPtr<BuildingBlock>>> mBlocksByGuid;
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitGroupShapeEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitGroupShapeEnd ( System::SharedPtr< Aspose::Words::Drawing::GroupShape groupShape)
virtual

Called when enumeration of a group shape has ended.

Parameters
groupShapeThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to create a group of shapes, and print its contents using a document visitor.

void GroupOfShapes()
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// If you need to create "NonPrimitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped,
// TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, DiagonalCornersRounded
// please use DocumentBuilder.InsertShape methods.
auto balloon = MakeObject<Shape>(doc, ShapeType::Balloon);
balloon->set_Width(200);
balloon->set_Height(200);
balloon->get_Stroke()->set_Color(System::Drawing::Color::get_Red());
auto cube = MakeObject<Shape>(doc, ShapeType::Cube);
cube->set_Width(100);
cube->set_Height(100);
cube->get_Stroke()->set_Color(System::Drawing::Color::get_Blue());
auto group = MakeObject<GroupShape>(doc);
group->AppendChild(balloon);
group->AppendChild(cube);
ASSERT_TRUE(group->get_IsGroup());
builder->InsertNode(group);
auto printer = MakeObject<ExDrawing::ShapeGroupPrinter>();
group->Accept(printer);
std::cout << printer->GetText() << std::endl;
}
class ShapeGroupPrinter : public DocumentVisitor
{
public:
ShapeGroupPrinter()
{
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"Shape group started:");
}
VisitorAction VisitGroupShapeEnd(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"End of shape group");
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(String(u"\tShape - ") + System::ObjectExt::ToString(shape->get_ShapeType()) + u":");
mBuilder->AppendLine(String(u"\t\tWidth: ") + shape->get_Width());
mBuilder->AppendLine(String(u"\t\tHeight: ") + shape->get_Height());
mBuilder->AppendLine(String(u"\t\tStroke color: ") + shape->get_Stroke()->get_Color());
mBuilder->AppendLine(String(u"\t\tFill color: ") + shape->get_Fill()->get_ForeColor());
}
VisitorAction VisitShapeEnd(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(u"\tEnd of shape");
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitGroupShapeStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitGroupShapeStart ( System::SharedPtr< Aspose::Words::Drawing::GroupShape groupShape)
virtual

Called when enumeration of a group shape has started.

Parameters
groupShapeThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to create a group of shapes, and print its contents using a document visitor.

void GroupOfShapes()
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// If you need to create "NonPrimitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped,
// TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, DiagonalCornersRounded
// please use DocumentBuilder.InsertShape methods.
auto balloon = MakeObject<Shape>(doc, ShapeType::Balloon);
balloon->set_Width(200);
balloon->set_Height(200);
balloon->get_Stroke()->set_Color(System::Drawing::Color::get_Red());
auto cube = MakeObject<Shape>(doc, ShapeType::Cube);
cube->set_Width(100);
cube->set_Height(100);
cube->get_Stroke()->set_Color(System::Drawing::Color::get_Blue());
auto group = MakeObject<GroupShape>(doc);
group->AppendChild(balloon);
group->AppendChild(cube);
ASSERT_TRUE(group->get_IsGroup());
builder->InsertNode(group);
auto printer = MakeObject<ExDrawing::ShapeGroupPrinter>();
group->Accept(printer);
std::cout << printer->GetText() << std::endl;
}
class ShapeGroupPrinter : public DocumentVisitor
{
public:
ShapeGroupPrinter()
{
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"Shape group started:");
}
VisitorAction VisitGroupShapeEnd(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"End of shape group");
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(String(u"\tShape - ") + System::ObjectExt::ToString(shape->get_ShapeType()) + u":");
mBuilder->AppendLine(String(u"\t\tWidth: ") + shape->get_Width());
mBuilder->AppendLine(String(u"\t\tHeight: ") + shape->get_Height());
mBuilder->AppendLine(String(u"\t\tStroke color: ") + shape->get_Stroke()->get_Color());
mBuilder->AppendLine(String(u"\t\tFill color: ") + shape->get_Fill()->get_ForeColor());
}
VisitorAction VisitShapeEnd(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(u"\tEnd of shape");
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitHeaderFooterEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitHeaderFooterEnd ( System::SharedPtr< Aspose::Words::HeaderFooter headerFooter)
virtual

Called when enumeration of a header or footer in a section has ended.

Parameters
headerFooterThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every header and footer in a document.

void HeaderFooterToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::HeaderFooterStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// An alternative way of accessing a document's header/footers section-by-section is by accessing the collection.
ArrayPtr<SharedPtr<HeaderFooter>> headerFooters = doc->get_FirstSection()->get_HeadersFooters()->ToArray();
ASSERT_EQ(3, headerFooters->get_Length());
}
class HeaderFooterStructurePrinter : public DocumentVisitor
{
public:
HeaderFooterStructurePrinter() : mVisitorIsInsideHeaderFooter(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideHeaderFooter = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideHeaderFooter)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitHeaderFooterStart(SharedPtr<HeaderFooter> headerFooter) override
{
IndentAndAppendLine(String(u"[HeaderFooter start] HeaderFooterType: ") + System::ObjectExt::ToString(headerFooter->get_HeaderFooterType()));
mDocTraversalDepth++;
mVisitorIsInsideHeaderFooter = true;
}
VisitorAction VisitHeaderFooterEnd(SharedPtr<HeaderFooter> headerFooter) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[HeaderFooter end]");
mVisitorIsInsideHeaderFooter = false;
}
private:
bool mVisitorIsInsideHeaderFooter;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitHeaderFooterStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitHeaderFooterStart ( System::SharedPtr< Aspose::Words::HeaderFooter headerFooter)
virtual

Called when enumeration of a header or footer in a section has started.

Parameters
headerFooterThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every header and footer in a document.

void HeaderFooterToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::HeaderFooterStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
// An alternative way of accessing a document's header/footers section-by-section is by accessing the collection.
ArrayPtr<SharedPtr<HeaderFooter>> headerFooters = doc->get_FirstSection()->get_HeadersFooters()->ToArray();
ASSERT_EQ(3, headerFooters->get_Length());
}
class HeaderFooterStructurePrinter : public DocumentVisitor
{
public:
HeaderFooterStructurePrinter() : mVisitorIsInsideHeaderFooter(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideHeaderFooter = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideHeaderFooter)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitHeaderFooterStart(SharedPtr<HeaderFooter> headerFooter) override
{
IndentAndAppendLine(String(u"[HeaderFooter start] HeaderFooterType: ") + System::ObjectExt::ToString(headerFooter->get_HeaderFooterType()));
mDocTraversalDepth++;
mVisitorIsInsideHeaderFooter = true;
}
VisitorAction VisitHeaderFooterEnd(SharedPtr<HeaderFooter> headerFooter) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[HeaderFooter end]");
mVisitorIsInsideHeaderFooter = false;
}
private:
bool mVisitorIsInsideHeaderFooter;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitOfficeMathEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitOfficeMathEnd ( System::SharedPtr< Aspose::Words::Math::OfficeMath officeMath)
virtual

Called when enumeration of a Office Math object has ended.

Parameters
officeMathThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every office math node in a document.

void OfficeMathToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::OfficeMathStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class OfficeMathStructurePrinter : public DocumentVisitor
{
public:
OfficeMathStructurePrinter() : mVisitorIsInsideOfficeMath(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideOfficeMath = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideOfficeMath)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitOfficeMathStart(SharedPtr<OfficeMath> officeMath) override
{
IndentAndAppendLine(String(u"[OfficeMath start] Math object type: ") + System::ObjectExt::ToString(officeMath->get_MathObjectType()));
mDocTraversalDepth++;
mVisitorIsInsideOfficeMath = true;
}
VisitorAction VisitOfficeMathEnd(SharedPtr<OfficeMath> officeMath) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[OfficeMath end]");
mVisitorIsInsideOfficeMath = false;
}
private:
bool mVisitorIsInsideOfficeMath;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitOfficeMathStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitOfficeMathStart ( System::SharedPtr< Aspose::Words::Math::OfficeMath officeMath)
virtual

Called when enumeration of a Office Math object has started.

Parameters
officeMathThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every office math node in a document.

void OfficeMathToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::OfficeMathStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class OfficeMathStructurePrinter : public DocumentVisitor
{
public:
OfficeMathStructurePrinter() : mVisitorIsInsideOfficeMath(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideOfficeMath = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideOfficeMath)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitOfficeMathStart(SharedPtr<OfficeMath> officeMath) override
{
IndentAndAppendLine(String(u"[OfficeMath start] Math object type: ") + System::ObjectExt::ToString(officeMath->get_MathObjectType()));
mDocTraversalDepth++;
mVisitorIsInsideOfficeMath = true;
}
VisitorAction VisitOfficeMathEnd(SharedPtr<OfficeMath> officeMath) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[OfficeMath end]");
mVisitorIsInsideOfficeMath = false;
}
private:
bool mVisitorIsInsideOfficeMath;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitParagraphEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitParagraphEnd ( System::SharedPtr< Aspose::Words::Paragraph paragraph)
virtual

Called when enumeration of a paragraph has ended.

Parameters
paragraphThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitParagraphStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitParagraphStart ( System::SharedPtr< Aspose::Words::Paragraph paragraph)
virtual

Called when enumeration of a paragraph has started.

Parameters
paragraphThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitRowEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitRowEnd ( System::SharedPtr< Aspose::Words::Tables::Row row)
virtual

Called when enumeration of a table row has ended.

Parameters
rowThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitRowStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitRowStart ( System::SharedPtr< Aspose::Words::Tables::Row row)
virtual

Called when enumeration of a table row has started.

Parameters
rowThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};

◆ VisitRun()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitRun ( System::SharedPtr< Aspose::Words::Run run)
virtual

Called when a run of text in the is encountered.

Parameters
runThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitSectionEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSectionEnd ( System::SharedPtr< Aspose::Words::Section section)
virtual

Called when enumeration of a section has ended.

Parameters
sectionThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitSectionStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSectionStart ( System::SharedPtr< Aspose::Words::Section section)
virtual

Called when enumeration of a section has started.

Parameters
sectionThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitShapeEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitShapeEnd ( System::SharedPtr< Aspose::Words::Drawing::Shape shape)
virtual

Called when enumeration of a shape has ended.

Parameters
shapeThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to create a group of shapes, and print its contents using a document visitor.

void GroupOfShapes()
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// If you need to create "NonPrimitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped,
// TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, DiagonalCornersRounded
// please use DocumentBuilder.InsertShape methods.
auto balloon = MakeObject<Shape>(doc, ShapeType::Balloon);
balloon->set_Width(200);
balloon->set_Height(200);
balloon->get_Stroke()->set_Color(System::Drawing::Color::get_Red());
auto cube = MakeObject<Shape>(doc, ShapeType::Cube);
cube->set_Width(100);
cube->set_Height(100);
cube->get_Stroke()->set_Color(System::Drawing::Color::get_Blue());
auto group = MakeObject<GroupShape>(doc);
group->AppendChild(balloon);
group->AppendChild(cube);
ASSERT_TRUE(group->get_IsGroup());
builder->InsertNode(group);
auto printer = MakeObject<ExDrawing::ShapeGroupPrinter>();
group->Accept(printer);
std::cout << printer->GetText() << std::endl;
}
class ShapeGroupPrinter : public DocumentVisitor
{
public:
ShapeGroupPrinter()
{
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"Shape group started:");
}
VisitorAction VisitGroupShapeEnd(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"End of shape group");
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(String(u"\tShape - ") + System::ObjectExt::ToString(shape->get_ShapeType()) + u":");
mBuilder->AppendLine(String(u"\t\tWidth: ") + shape->get_Width());
mBuilder->AppendLine(String(u"\t\tHeight: ") + shape->get_Height());
mBuilder->AppendLine(String(u"\t\tStroke color: ") + shape->get_Stroke()->get_Color());
mBuilder->AppendLine(String(u"\t\tFill color: ") + shape->get_Fill()->get_ForeColor());
}
VisitorAction VisitShapeEnd(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(u"\tEnd of shape");
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
};

◆ VisitShapeStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitShapeStart ( System::SharedPtr< Aspose::Words::Drawing::Shape shape)
virtual

Called when enumeration of a shape has started.

Parameters
shapeThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to create a group of shapes, and print its contents using a document visitor.

void GroupOfShapes()
{
auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// If you need to create "NonPrimitive" shapes, such as SingleCornerSnipped, TopCornersSnipped, DiagonalCornersSnipped,
// TopCornersOneRoundedOneSnipped, SingleCornerRounded, TopCornersRounded, DiagonalCornersRounded
// please use DocumentBuilder.InsertShape methods.
auto balloon = MakeObject<Shape>(doc, ShapeType::Balloon);
balloon->set_Width(200);
balloon->set_Height(200);
balloon->get_Stroke()->set_Color(System::Drawing::Color::get_Red());
auto cube = MakeObject<Shape>(doc, ShapeType::Cube);
cube->set_Width(100);
cube->set_Height(100);
cube->get_Stroke()->set_Color(System::Drawing::Color::get_Blue());
auto group = MakeObject<GroupShape>(doc);
group->AppendChild(balloon);
group->AppendChild(cube);
ASSERT_TRUE(group->get_IsGroup());
builder->InsertNode(group);
auto printer = MakeObject<ExDrawing::ShapeGroupPrinter>();
group->Accept(printer);
std::cout << printer->GetText() << std::endl;
}
class ShapeGroupPrinter : public DocumentVisitor
{
public:
ShapeGroupPrinter()
{
mBuilder = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"Shape group started:");
}
VisitorAction VisitGroupShapeEnd(SharedPtr<GroupShape> groupShape) override
{
mBuilder->AppendLine(u"End of shape group");
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(String(u"\tShape - ") + System::ObjectExt::ToString(shape->get_ShapeType()) + u":");
mBuilder->AppendLine(String(u"\t\tWidth: ") + shape->get_Width());
mBuilder->AppendLine(String(u"\t\tHeight: ") + shape->get_Height());
mBuilder->AppendLine(String(u"\t\tStroke color: ") + shape->get_Stroke()->get_Color());
mBuilder->AppendLine(String(u"\t\tFill color: ") + shape->get_Fill()->get_ForeColor());
}
VisitorAction VisitShapeEnd(SharedPtr<Shape> shape) override
{
mBuilder->AppendLine(u"\tEnd of shape");
}
private:
SharedPtr<System::Text::StringBuilder> mBuilder;
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitSmartTagEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSmartTagEnd ( System::SharedPtr< Aspose::Words::Markup::SmartTag smartTag)
virtual

Called when enumeration of a smart tag has ended.

Parameters
smartTagThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every smart tag in a document.

void SmartTagToText()
{
auto doc = MakeObject<Document>(MyDir + u"Smart tags.doc");
auto visitor = MakeObject<ExDocumentVisitor::SmartTagStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class SmartTagStructurePrinter : public DocumentVisitor
{
public:
SmartTagStructurePrinter() : mVisitorIsInsideSmartTag(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideSmartTag = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideSmartTag)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitSmartTagStart(SharedPtr<SmartTag> smartTag) override
{
IndentAndAppendLine(String(u"[SmartTag start] Name: ") + smartTag->get_Element());
mDocTraversalDepth++;
mVisitorIsInsideSmartTag = true;
}
VisitorAction VisitSmartTagEnd(SharedPtr<SmartTag> smartTag) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[SmartTag end]");
mVisitorIsInsideSmartTag = false;
}
private:
bool mVisitorIsInsideSmartTag;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitSmartTagStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSmartTagStart ( System::SharedPtr< Aspose::Words::Markup::SmartTag smartTag)
virtual

Called when enumeration of a smart tag has started.

Parameters
smartTagThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every smart tag in a document.

void SmartTagToText()
{
auto doc = MakeObject<Document>(MyDir + u"Smart tags.doc");
auto visitor = MakeObject<ExDocumentVisitor::SmartTagStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class SmartTagStructurePrinter : public DocumentVisitor
{
public:
SmartTagStructurePrinter() : mVisitorIsInsideSmartTag(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideSmartTag = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideSmartTag)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitSmartTagStart(SharedPtr<SmartTag> smartTag) override
{
IndentAndAppendLine(String(u"[SmartTag start] Name: ") + smartTag->get_Element());
mDocTraversalDepth++;
mVisitorIsInsideSmartTag = true;
}
VisitorAction VisitSmartTagEnd(SharedPtr<SmartTag> smartTag) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[SmartTag end]");
mVisitorIsInsideSmartTag = false;
}
private:
bool mVisitorIsInsideSmartTag;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitSpecialChar()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSpecialChar ( System::SharedPtr< Aspose::Words::SpecialChar specialChar)
virtual

Called when a SpecialChar node is encountered in the document.

Parameters
specialCharThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitStructuredDocumentTagEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitStructuredDocumentTagEnd ( System::SharedPtr< Aspose::Words::Markup::StructuredDocumentTag sdt)
virtual

Called when enumeration of a structured document tag has ended.

Parameters
sdtThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every structured document tag in a document.

void StructuredDocumentTagToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::StructuredDocumentTagNodePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class StructuredDocumentTagNodePrinter : public DocumentVisitor
{
public:
StructuredDocumentTagNodePrinter() : mVisitorIsInsideStructuredDocumentTag(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideStructuredDocumentTag = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideStructuredDocumentTag)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitStructuredDocumentTagStart(SharedPtr<StructuredDocumentTag> sdt) override
{
IndentAndAppendLine(String(u"[StructuredDocumentTag start] Title: ") + sdt->get_Title());
mDocTraversalDepth++;
}
VisitorAction VisitStructuredDocumentTagEnd(SharedPtr<StructuredDocumentTag> sdt) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[StructuredDocumentTag end]");
}
private:
bool mVisitorIsInsideStructuredDocumentTag;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitStructuredDocumentTagRangeEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitStructuredDocumentTagRangeEnd ( System::SharedPtr< Aspose::Words::Markup::StructuredDocumentTagRangeEnd sdtRangeEnd)
virtual

◆ VisitStructuredDocumentTagRangeStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitStructuredDocumentTagRangeStart ( System::SharedPtr< Aspose::Words::Markup::StructuredDocumentTagRangeStart sdtRangeStart)
virtual

◆ VisitStructuredDocumentTagStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitStructuredDocumentTagStart ( System::SharedPtr< Aspose::Words::Markup::StructuredDocumentTag sdt)
virtual

Called when enumeration of a structured document tag has started.

Parameters
sdtThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every structured document tag in a document.

void StructuredDocumentTagToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::StructuredDocumentTagNodePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class StructuredDocumentTagNodePrinter : public DocumentVisitor
{
public:
StructuredDocumentTagNodePrinter() : mVisitorIsInsideStructuredDocumentTag(false), mDocTraversalDepth(0)
{
mBuilder = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideStructuredDocumentTag = false;
}
String GetText()
{
return mBuilder->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideStructuredDocumentTag)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitStructuredDocumentTagStart(SharedPtr<StructuredDocumentTag> sdt) override
{
IndentAndAppendLine(String(u"[StructuredDocumentTag start] Title: ") + sdt->get_Title());
mDocTraversalDepth++;
}
VisitorAction VisitStructuredDocumentTagEnd(SharedPtr<StructuredDocumentTag> sdt) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[StructuredDocumentTag end]");
}
private:
bool mVisitorIsInsideStructuredDocumentTag;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mBuilder;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mBuilder->Append(u"| ");
}
mBuilder->AppendLine(text);
}
};

◆ VisitSubDocument()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitSubDocument ( System::SharedPtr< Aspose::Words::SubDocument subDocument)
virtual

Called when a subDocument is encountered.

Parameters
subDocumentThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to use a document visitor to print a document's node structure.

void DocStructureToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::DocStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class DocStructurePrinter : public DocumentVisitor
{
public:
DocStructurePrinter() : mDocTraversalDepth(0)
{
mAcceptingNodeChildTree = MakeObject<System::Text::StringBuilder>();
}
String GetText()
{
return mAcceptingNodeChildTree->ToString();
}
VisitorAction VisitDocumentStart(SharedPtr<Document> doc) override
{
int childNodeCount = doc->GetChildNodes(NodeType::Any, true)->get_Count();
IndentAndAppendLine(String(u"[Document start] Child nodes: ") + childNodeCount);
mDocTraversalDepth++;
// Allow the visitor to continue visiting other nodes.
}
VisitorAction VisitDocumentEnd(SharedPtr<Document> doc) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Document end]");
}
VisitorAction VisitSectionStart(SharedPtr<Section> section) override
{
// Get the index of our section within the document.
SharedPtr<NodeCollection> docSections = section->get_Document()->GetChildNodes(NodeType::Section, false);
int sectionIndex = docSections->IndexOf(section);
IndentAndAppendLine(String(u"[Section start] Section index: ") + sectionIndex);
mDocTraversalDepth++;
}
VisitorAction VisitSectionEnd(SharedPtr<Section> section) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Section end]");
}
VisitorAction VisitBodyStart(SharedPtr<Body> body) override
{
int paragraphCount = body->get_Paragraphs()->get_Count();
IndentAndAppendLine(String(u"[Body start] Paragraphs: ") + paragraphCount);
mDocTraversalDepth++;
}
VisitorAction VisitBodyEnd(SharedPtr<Body> body) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Body end]");
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
IndentAndAppendLine(u"[Paragraph start]");
mDocTraversalDepth++;
}
VisitorAction VisitParagraphEnd(SharedPtr<Paragraph> paragraph) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Paragraph end]");
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
VisitorAction VisitSubDocument(SharedPtr<SubDocument> subDocument) override
{
IndentAndAppendLine(u"[SubDocument]");
}
private:
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mAcceptingNodeChildTree;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mAcceptingNodeChildTree->Append(u"| ");
}
mAcceptingNodeChildTree->AppendLine(text);
}
};

◆ VisitTableEnd()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitTableEnd ( System::SharedPtr< Aspose::Words::Tables::Table table)
virtual

Called when enumeration of a table has ended.

Parameters
tableThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};

Shows how to use a DocumentVisitor implementation to remove all hidden content from a document.

void RemoveHiddenContentFromDocument()
{
auto doc = MakeObject<Document>(MyDir + u"Hidden content.docx");
auto hiddenContentRemover = MakeObject<ExFont::RemoveHiddenContentVisitor>();
// Below are three types of fields which can accept a document visitor,
// which will allow it to visit the accepting node, and then traverse its child nodes in a depth-first manner.
// 1 - Paragraph node:
auto para = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 4, true));
para->Accept(hiddenContentRemover);
// 2 - Table node:
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
table->Accept(hiddenContentRemover);
// 3 - Document node:
doc->Accept(hiddenContentRemover);
doc->Save(ArtifactsDir + u"Font.RemoveHiddenContentFromDocument.docx");
}
class RemoveHiddenContentVisitor : public DocumentVisitor
{
public:
VisitorAction VisitFieldStart(SharedPtr<FieldStart> fieldStart) override
{
if (fieldStart->get_Font()->get_Hidden())
{
fieldStart->Remove();
}
}
VisitorAction VisitFieldEnd(SharedPtr<FieldEnd> fieldEnd) override
{
if (fieldEnd->get_Font()->get_Hidden())
{
fieldEnd->Remove();
}
}
VisitorAction VisitFieldSeparator(SharedPtr<FieldSeparator> fieldSeparator) override
{
if (fieldSeparator->get_Font()->get_Hidden())
{
fieldSeparator->Remove();
}
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (run->get_Font()->get_Hidden())
{
run->Remove();
}
}
VisitorAction VisitParagraphStart(SharedPtr<Paragraph> paragraph) override
{
if (paragraph->get_ParagraphBreakFont()->get_Hidden())
{
paragraph->Remove();
}
}
VisitorAction VisitFormField(SharedPtr<FormField> formField) override
{
if (formField->get_Font()->get_Hidden())
{
formField->Remove();
}
}
VisitorAction VisitGroupShapeStart(SharedPtr<GroupShape> groupShape) override
{
if (groupShape->get_Font()->get_Hidden())
{
groupShape->Remove();
}
}
VisitorAction VisitShapeStart(SharedPtr<Shape> shape) override
{
if (shape->get_Font()->get_Hidden())
{
shape->Remove();
}
}
VisitorAction VisitCommentStart(SharedPtr<Comment> comment) override
{
if (comment->get_Font()->get_Hidden())
{
comment->Remove();
}
}
VisitorAction VisitFootnoteStart(SharedPtr<Footnote> footnote) override
{
if (footnote->get_Font()->get_Hidden())
{
footnote->Remove();
}
}
VisitorAction VisitSpecialChar(SharedPtr<SpecialChar> specialChar) override
{
if (specialChar->get_Font()->get_Hidden())
{
specialChar->Remove();
}
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
// The content inside table cells may have the hidden content flag, but the tables themselves cannot.
// If this table had nothing but hidden content, this visitor would have removed all of it,
// and there would be no child nodes left.
// Thus, we can also treat the table itself as hidden content and remove it.
// Tables which are empty but do not have hidden content will have cells with empty paragraphs inside,
// which this visitor will not remove.
if (!table->get_HasChildNodes())
{
table->Remove();
}
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
if (!cell->get_HasChildNodes() && cell->get_ParentNode() != nullptr)
{
cell->Remove();
}
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
if (!row->get_HasChildNodes() && row->get_ParentNode() != nullptr)
{
row->Remove();
}
}
};

◆ VisitTableStart()

virtual Aspose::Words::VisitorAction Aspose::Words::DocumentVisitor::VisitTableStart ( System::SharedPtr< Aspose::Words::Tables::Table table)
virtual

Called when enumeration of a table has started.

Parameters
tableThe object that is being visited.
Returns
A VisitorAction value that specifies how to continue the enumeration.
Examples

Shows how to print the node structure of every table in a document.

void TableToText()
{
auto doc = MakeObject<Document>(MyDir + u"DocumentVisitor-compatible features.docx");
auto visitor = MakeObject<ExDocumentVisitor::TableStructurePrinter>();
// When we get a composite node to accept a document visitor, the visitor visits the accepting node,
// and then traverses all the node's children in a depth-first manner.
// The visitor can read and modify each visited node.
doc->Accept(visitor);
std::cout << visitor->GetText() << std::endl;
}
class TableStructurePrinter : public DocumentVisitor
{
public:
TableStructurePrinter() : mVisitorIsInsideTable(false), mDocTraversalDepth(0)
{
mVisitedTables = MakeObject<System::Text::StringBuilder>();
mVisitorIsInsideTable = false;
}
String GetText()
{
return mVisitedTables->ToString();
}
VisitorAction VisitRun(SharedPtr<Run> run) override
{
if (mVisitorIsInsideTable)
{
IndentAndAppendLine(String(u"[Run] \"") + run->GetText() + u"\"");
}
}
VisitorAction VisitTableStart(SharedPtr<Table> table) override
{
int rows = 0;
int columns = 0;
if (table->get_Rows()->get_Count() > 0)
{
rows = table->get_Rows()->get_Count();
columns = table->get_FirstRow()->get_Count();
}
IndentAndAppendLine(String(u"[Table start] Size: ") + rows + u"x" + columns);
mDocTraversalDepth++;
mVisitorIsInsideTable = true;
}
VisitorAction VisitTableEnd(SharedPtr<Table> table) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Table end]");
mVisitorIsInsideTable = false;
}
VisitorAction VisitRowStart(SharedPtr<Row> row) override
{
String rowContents = row->GetText().TrimEnd(MakeArray<char16_t>({u'\x0007', u' '})).Replace(u"\u0007", u", ");
int rowWidth = row->IndexOf(row->get_LastCell()) + 1;
int rowIndex = row->get_ParentTable()->IndexOf(row);
String rowStatusInTable = row->get_IsFirstRow() && row->get_IsLastRow() ? u"only"
: row->get_IsFirstRow() ? u"first"
: row->get_IsLastRow() ? String(u"last")
: String(u"");
if (rowStatusInTable != u"")
{
rowStatusInTable = String::Format(u", the {0} row in this table,", rowStatusInTable);
}
IndentAndAppendLine(String::Format(u"[Row start] Row #{0}{1} width {2}, \"{3}\"", ++rowIndex, rowStatusInTable, rowWidth, rowContents));
mDocTraversalDepth++;
}
VisitorAction VisitRowEnd(SharedPtr<Row> row) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Row end]");
}
VisitorAction VisitCellStart(SharedPtr<Cell> cell) override
{
SharedPtr<Row> row = cell->get_ParentRow();
SharedPtr<Table> table = row->get_ParentTable();
String cellStatusInRow = cell->get_IsFirstCell() && cell->get_IsLastCell() ? u"only"
: cell->get_IsFirstCell() ? u"first"
: cell->get_IsLastCell() ? String(u"last")
: String(u"");
if (cellStatusInRow != u"")
{
cellStatusInRow = String::Format(u", the {0} cell in this row", cellStatusInRow);
}
IndentAndAppendLine(String::Format(u"[Cell start] Row {0}, Col {1}{2}", table->IndexOf(row) + 1, row->IndexOf(cell) + 1, cellStatusInRow));
mDocTraversalDepth++;
}
VisitorAction VisitCellEnd(SharedPtr<Cell> cell) override
{
mDocTraversalDepth--;
IndentAndAppendLine(u"[Cell end]");
}
private:
bool mVisitorIsInsideTable;
int mDocTraversalDepth;
SharedPtr<System::Text::StringBuilder> mVisitedTables;
void IndentAndAppendLine(String text)
{
for (int i = 0; i < mDocTraversalDepth; i++)
{
mVisitedTables->Append(u"| ");
}
mVisitedTables->AppendLine(text);
}
};