Aspose::Words::NodeCollection Class Reference

Detailed Description

Represents a collection of nodes of a specific type.

NodeCollection does not own the nodes it contains, rather, is just a selection of nodes of the specified type, but the nodes are stored in the tree under their respective parent nodes.

NodeCollection supports indexed access, iteration and provides add and remove methods.

The NodeCollection collection is "live", i.e. changes to the children of the node object that it was created from are immediately reflected in the nodes returned by the NodeCollection properties and methods.

NodeCollection is returned by GetChildNodes() and also serves as a base class for typed node collections such as SectionCollection, ParagraphCollection etc.

NodeCollection can be "flat" and contain only immediate children of the node it was created from, or it can be "deep" and contain all descendant children.

Examples

Shows how to replace all textbox shapes with image shapes.

auto doc = MakeObject<Document>(MyDir + u"Textboxes in drawing canvas.docx");
ArrayPtr<SharedPtr<Shape>> shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_OfType<SharedPtr<Shape>>()->LINQ_ToArray();
auto isTextBox = [](SharedPtr<Shape> s)
{
return s->get_ShapeType() == ShapeType::TextBox;
};
auto isImage = [](SharedPtr<Shape> s)
{
return s->get_ShapeType() == ShapeType::Image;
};
ASSERT_EQ(3, shapes->LINQ_Count(isTextBox));
ASSERT_EQ(1, shapes->LINQ_Count(isImage));
for (SharedPtr<Shape> shape : shapes)
{
if (shape->get_ShapeType() == ShapeType::TextBox)
{
auto replacementShape = MakeObject<Shape>(doc, ShapeType::Image);
replacementShape->get_ImageData()->SetImage(ImageDir + u"Logo.jpg");
replacementShape->set_Left(shape->get_Left());
replacementShape->set_Top(shape->get_Top());
replacementShape->set_Width(shape->get_Width());
replacementShape->set_Height(shape->get_Height());
replacementShape->set_RelativeHorizontalPosition(shape->get_RelativeHorizontalPosition());
replacementShape->set_RelativeVerticalPosition(shape->get_RelativeVerticalPosition());
replacementShape->set_HorizontalAlignment(shape->get_HorizontalAlignment());
replacementShape->set_VerticalAlignment(shape->get_VerticalAlignment());
replacementShape->set_WrapType(shape->get_WrapType());
replacementShape->set_WrapSide(shape->get_WrapSide());
shape->get_ParentNode()->InsertAfter(replacementShape, shape);
shape->Remove();
}
}
shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_OfType<SharedPtr<Shape>>()->LINQ_ToArray();
ASSERT_EQ(0, shapes->LINQ_Count(isTextBox));
ASSERT_EQ(4, shapes->LINQ_Count(isImage));
doc->Save(ArtifactsDir + u"Shape.ReplaceTextboxesWithImages.docx");

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

+ Inheritance diagram for Aspose::Words::NodeCollection:

Public Member Functions

void Add (const SharedPtr< Node > &node)
 Adds a node to the end of the collection. More...
 
void Clear ()
 Removes all nodes from this collection and from the document. More...
 
bool Contains (const SharedPtr< Node > &node)
 Determines whether a node is in the collection. More...
 
int32_t get_Count ()
 Gets the number of nodes in the collection. More...
 
SharedPtr< IEnumerator< SharedPtr< Node > > > GetEnumerator () override
 Provides a simple "foreach" style iteration over the collection of nodes. More...
 
virtual const TypeInfoGetType () const override
 
SharedPtr< Nodeidx_get (int32_t index)
 Retrieves a node at the given index. More...
 
int32_t IndexOf (const SharedPtr< Node > &node)
 Returns the zero-based index of the specified node. More...
 
void Insert (int32_t index, const SharedPtr< Node > &node)
 Inserts a node into the collection at the specified index. More...
 
virtual bool Is (const TypeInfo &target) const override
 
void Remove (const SharedPtr< Node > &node)
 Removes the node from the collection and from the document. More...
 
void RemoveAt (int32_t index)
 Removes the node at the specified index from the collection and from the document. More...
 
ArrayPtr< SharedPtr< Node > > ToArray ()
 Copies all nodes from the collection to a new array of nodes. More...
 

Static Public Member Functions

static const TypeInfoType ()
 

Member Function Documentation

◆ Add()

void Aspose::Words::NodeCollection::Add ( const System::SharedPtr< Aspose::Words::Node > &  node)

Adds a node to the end of the collection.

The node is inserted as a child into the node object from which the collection was created.

If the newChild is already in the tree, it is first removed.

If the node being inserted was created from another document, you should use ImportNode() to import the node to the current document. The imported node can then be inserted into the current document.

Parameters
nodeThe node to be added to the end of the collection.
Exceptions
System::NotSupportedExceptionThe NodeCollection is a "deep" collection.
Examples

Shows how to prepare a new section node for editing.

auto doc = MakeObject<Document>();
// A blank document comes with a section, which has a body, which in turn has a paragraph.
// We can add contents to this document by adding elements such as text runs, shapes, or tables to that paragraph.
ASSERT_EQ(NodeType::Section, doc->GetChild(NodeType::Any, 0, true)->get_NodeType());
ASSERT_EQ(NodeType::Body, doc->get_Sections()->idx_get(0)->GetChild(NodeType::Any, 0, true)->get_NodeType());
ASSERT_EQ(NodeType::Paragraph, doc->get_Sections()->idx_get(0)->get_Body()->GetChild(NodeType::Any, 0, true)->get_NodeType());
// If we add a new section like this, it will not have a body, or any other child nodes.
doc->get_Sections()->Add(MakeObject<Section>(doc));
ASSERT_EQ(0, doc->get_Sections()->idx_get(1)->GetChildNodes(NodeType::Any, true)->get_Count());
// Run the "EnsureMinimum" method to add a body and a paragraph to this section to begin editing it.
doc->get_LastSection()->EnsureMinimum();
ASSERT_EQ(NodeType::Body, doc->get_Sections()->idx_get(1)->GetChild(NodeType::Any, 0, true)->get_NodeType());
ASSERT_EQ(NodeType::Paragraph, doc->get_Sections()->idx_get(1)->get_Body()->GetChild(NodeType::Any, 0, true)->get_NodeType());
doc->get_Sections()->idx_get(0)->get_Body()->get_FirstParagraph()->AppendChild(MakeObject<Run>(doc, u"Hello world!"));
ASSERT_EQ(u"Hello world!", doc->GetText().Trim());

◆ Clear()

void Aspose::Words::NodeCollection::Clear ( )

Removes all nodes from this collection and from the document.

Examples

Shows how to remove all sections from a document.

auto doc = MakeObject<Document>(MyDir + u"Document.docx");
// This document has one section with a few child nodes containing and displaying all the document's contents.
ASSERT_EQ(1, doc->get_Sections()->get_Count());
ASSERT_EQ(17, doc->get_Sections()->idx_get(0)->GetChildNodes(NodeType::Any, true)->get_Count());
ASSERT_EQ(u"Hello World!\r\rHello Word!\r\r\rHello World!", doc->GetText().Trim());
// Clear the collection of sections, which will remove all of the document's children.
doc->get_Sections()->Clear();
ASSERT_EQ(0, doc->GetChildNodes(NodeType::Any, true)->get_Count());
ASSERT_EQ(String::Empty, doc->GetText().Trim());

◆ Contains()

bool Aspose::Words::NodeCollection::Contains ( const System::SharedPtr< Aspose::Words::Node > &  node)

Determines whether a node is in the collection.

This method performs a linear search; therefore, the average execution time is proportional to Count.

Parameters
nodeThe node to locate.
Returns
True if item is found in the collection; otherwise, false.
Examples

Shows how to work with a NodeCollection.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// Add text to the document by inserting Runs using a DocumentBuilder.
builder->Write(u"Run 1. ");
builder->Write(u"Run 2. ");
// Every invocation of the "Write" method creates a new Run,
// which then appears in the parent Paragraph's RunCollection.
SharedPtr<RunCollection> runs = doc->get_FirstSection()->get_Body()->get_FirstParagraph()->get_Runs();
ASSERT_EQ(2, runs->get_Count());
// We can also insert a node into the RunCollection manually.
auto newRun = MakeObject<Run>(doc, u"Run 3. ");
runs->Insert(3, newRun);
ASSERT_TRUE(runs->Contains(newRun));
ASSERT_EQ(u"Run 1. Run 2. Run 3.", doc->GetText().Trim());
// Access individual runs and remove them to remove their text from the document.
SharedPtr<Run> run = runs->idx_get(1);
runs->Remove(run);
ASSERT_EQ(u"Run 1. Run 3.", doc->GetText().Trim());
ASSERT_FALSE(run == nullptr);
ASSERT_FALSE(runs->Contains(run));

◆ get_Count()

int32_t Aspose::Words::NodeCollection::get_Count ( )

Gets the number of nodes in the collection.

Examples

Shows how to traverse through a composite node's collection of child nodes.

auto doc = MakeObject<Document>();
// Add two runs and one shape as child nodes to the first paragraph of this document.
auto paragraph = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 0, true));
paragraph->AppendChild(MakeObject<Run>(doc, u"Hello world! "));
auto shape = MakeObject<Shape>(doc, ShapeType::Rectangle);
shape->set_Width(200);
shape->set_Height(200);
// Note that the 'CustomNodeId' is not saved to an output file and exists only during the node lifetime.
shape->set_CustomNodeId(100);
shape->set_WrapType(WrapType::Inline);
paragraph->AppendChild(shape);
paragraph->AppendChild(MakeObject<Run>(doc, u"Hello again!"));
// Iterate through the paragraph's collection of immediate children,
// and print any runs or shapes that we find within.
SharedPtr<NodeCollection> children = paragraph->get_ChildNodes();
ASSERT_EQ(3, paragraph->get_ChildNodes()->get_Count());
for (const auto& child : System::IterateOver(children))
{
switch (child->get_NodeType())
{
std::cout << "Run contents:" << std::endl;
std::cout << "\t\"" << child->GetText().Trim() << "\"" << std::endl;
break;
auto childShape = System::DynamicCast<Shape>(child);
std::cout << "Shape:" << std::endl;
std::cout << String::Format(u"\t{0}, {1}x{2}", childShape->get_ShapeType(), childShape->get_Width(), childShape->get_Height()) << std::endl;
ASSERT_EQ(100, shape->get_CustomNodeId());
break;
}
default:
break;
}
}

Shows how to find out if a tables are nested.

void CalculateDepthOfNestedTables()
{
auto doc = MakeObject<Document>(MyDir + u"Nested tables.docx");
SharedPtr<NodeCollection> tables = doc->GetChildNodes(NodeType::Table, true);
for (int i = 0; i < tables->get_Count(); i++)
{
auto table = System::DynamicCast<Table>(tables->idx_get(i));
// Find out if any cells in the table have other tables as children.
int count = GetChildTableCount(table);
std::cout << "Table #" << i << " has " << count << " tables directly within its cells" << std::endl;
// Find out if the table is nested inside another table, and, if so, at what depth.
int tableDepth = GetNestedDepthOfTable(table);
if (tableDepth > 0)
{
std::cout << "Table #" << i << " is nested inside another table at depth of " << tableDepth << std::endl;
}
else
{
std::cout << "Table #" << i << " is a non nested table (is not a child of another table)" << std::endl;
}
}
}
static int GetNestedDepthOfTable(SharedPtr<Table> table)
{
int depth = 0;
SharedPtr<Node> parent = table->GetAncestor(table->get_NodeType());
while (parent != nullptr)
{
depth++;
parent = parent->GetAncestorOf<SharedPtr<Table>>();
}
return depth;
}
static int GetChildTableCount(SharedPtr<Table> table)
{
int childTableCount = 0;
for (const auto& row : System::IterateOver(table->get_Rows()->LINQ_OfType<SharedPtr<Row>>()))
{
for (const auto& Cell : System::IterateOver(row->get_Cells()->LINQ_OfType<SharedPtr<Cell>>()))
{
SharedPtr<TableCollection> childTables = Cell->get_Tables();
if (childTables->get_Count() > 0)
{
childTableCount++;
}
}
}
return childTableCount;
}

◆ GetEnumerator()

System::SharedPtr<System::Collections::Generic::IEnumerator<System::SharedPtr<Aspose::Words::Node> > > Aspose::Words::NodeCollection::GetEnumerator ( )
override

Provides a simple "foreach" style iteration over the collection of nodes.

Returns
An IEnumerator.

◆ GetType()

◆ idx_get()

System::SharedPtr<Aspose::Words::Node> Aspose::Words::NodeCollection::idx_get ( int32_t  index)

Retrieves a node at the given index.

The index is zero-based.

Negative indexes are allowed and indicate access from the back of the collection. For example -1 means the last item, -2 means the second before last and so on.

If index is greater than or equal to the number of items in the list, this returns a null reference.

If index is negative and its absolute value is greater than the number of items in the list, this returns a null reference.

Parameters
indexAn index into the collection of nodes.
Examples

Shows how to traverse through a composite node's collection of child nodes.

auto doc = MakeObject<Document>();
// Add two runs and one shape as child nodes to the first paragraph of this document.
auto paragraph = System::DynamicCast<Paragraph>(doc->GetChild(NodeType::Paragraph, 0, true));
paragraph->AppendChild(MakeObject<Run>(doc, u"Hello world! "));
auto shape = MakeObject<Shape>(doc, ShapeType::Rectangle);
shape->set_Width(200);
shape->set_Height(200);
// Note that the 'CustomNodeId' is not saved to an output file and exists only during the node lifetime.
shape->set_CustomNodeId(100);
shape->set_WrapType(WrapType::Inline);
paragraph->AppendChild(shape);
paragraph->AppendChild(MakeObject<Run>(doc, u"Hello again!"));
// Iterate through the paragraph's collection of immediate children,
// and print any runs or shapes that we find within.
SharedPtr<NodeCollection> children = paragraph->get_ChildNodes();
ASSERT_EQ(3, paragraph->get_ChildNodes()->get_Count());
for (const auto& child : System::IterateOver(children))
{
switch (child->get_NodeType())
{
std::cout << "Run contents:" << std::endl;
std::cout << "\t\"" << child->GetText().Trim() << "\"" << std::endl;
break;
auto childShape = System::DynamicCast<Shape>(child);
std::cout << "Shape:" << std::endl;
std::cout << String::Format(u"\t{0}, {1}x{2}", childShape->get_ShapeType(), childShape->get_Width(), childShape->get_Height()) << std::endl;
ASSERT_EQ(100, shape->get_CustomNodeId());
break;
}
default:
break;
}
}

◆ IndexOf()

int32_t Aspose::Words::NodeCollection::IndexOf ( const System::SharedPtr< Aspose::Words::Node > &  node)

Returns the zero-based index of the specified node.

This method performs a linear search; therefore, the average execution time is proportional to Count.

Parameters
nodeThe node to locate.
Returns
The zero-based index of the node within the collection, if found; otherwise, -1.
Examples

Shows how to get the index of a node in a collection.

auto doc = MakeObject<Document>(MyDir + u"Tables.docx");
SharedPtr<Table> table = doc->get_FirstSection()->get_Body()->get_Tables()->idx_get(0);
SharedPtr<NodeCollection> allTables = doc->GetChildNodes(NodeType::Table, true);
ASSERT_EQ(0, allTables->IndexOf(table));
SharedPtr<Row> row = table->get_Rows()->idx_get(2);
ASSERT_EQ(2, table->IndexOf(row));
SharedPtr<Cell> cell = row->get_LastCell();
ASSERT_EQ(4, row->IndexOf(cell));

◆ Insert()

void Aspose::Words::NodeCollection::Insert ( int32_t  index,
const System::SharedPtr< Aspose::Words::Node > &  node 
)

Inserts a node into the collection at the specified index.

The node is inserted as a child into the node object from which the collection was created.

If the index is equal to or greater than Count, the node is added at the end of the collection.

If the index is negative and its absolute value is greater than Count, the node is added at the end of the collection.

If the newChild is already in the tree, it is first removed.

If the node being inserted was created from another document, you should use ImportNode() to import the node to the current document. The imported node can then be inserted into the current document.

Parameters
indexThe zero-based index of the node. Negative indexes are allowed and indicate access from the back of the list. For example -1 means the last node, -2 means the second before last and so on.
nodeThe node to insert.
Exceptions
System::NotSupportedExceptionThe NodeCollection is a "deep" collection.
Examples

Shows how to work with a NodeCollection.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// Add text to the document by inserting Runs using a DocumentBuilder.
builder->Write(u"Run 1. ");
builder->Write(u"Run 2. ");
// Every invocation of the "Write" method creates a new Run,
// which then appears in the parent Paragraph's RunCollection.
SharedPtr<RunCollection> runs = doc->get_FirstSection()->get_Body()->get_FirstParagraph()->get_Runs();
ASSERT_EQ(2, runs->get_Count());
// We can also insert a node into the RunCollection manually.
auto newRun = MakeObject<Run>(doc, u"Run 3. ");
runs->Insert(3, newRun);
ASSERT_TRUE(runs->Contains(newRun));
ASSERT_EQ(u"Run 1. Run 2. Run 3.", doc->GetText().Trim());
// Access individual runs and remove them to remove their text from the document.
SharedPtr<Run> run = runs->idx_get(1);
runs->Remove(run);
ASSERT_EQ(u"Run 1. Run 3.", doc->GetText().Trim());
ASSERT_FALSE(run == nullptr);
ASSERT_FALSE(runs->Contains(run));

◆ Is()

◆ Remove()

void Aspose::Words::NodeCollection::Remove ( const System::SharedPtr< Aspose::Words::Node > &  node)

Removes the node from the collection and from the document.

Parameters
nodeThe node to remove.
Examples

Shows how to work with a NodeCollection.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
// Add text to the document by inserting Runs using a DocumentBuilder.
builder->Write(u"Run 1. ");
builder->Write(u"Run 2. ");
// Every invocation of the "Write" method creates a new Run,
// which then appears in the parent Paragraph's RunCollection.
SharedPtr<RunCollection> runs = doc->get_FirstSection()->get_Body()->get_FirstParagraph()->get_Runs();
ASSERT_EQ(2, runs->get_Count());
// We can also insert a node into the RunCollection manually.
auto newRun = MakeObject<Run>(doc, u"Run 3. ");
runs->Insert(3, newRun);
ASSERT_TRUE(runs->Contains(newRun));
ASSERT_EQ(u"Run 1. Run 2. Run 3.", doc->GetText().Trim());
// Access individual runs and remove them to remove their text from the document.
SharedPtr<Run> run = runs->idx_get(1);
runs->Remove(run);
ASSERT_EQ(u"Run 1. Run 3.", doc->GetText().Trim());
ASSERT_FALSE(run == nullptr);
ASSERT_FALSE(runs->Contains(run));

◆ RemoveAt()

void Aspose::Words::NodeCollection::RemoveAt ( int32_t  index)

Removes the node at the specified index from the collection and from the document.

Parameters
indexThe zero-based index of the node. Negative indexes are allowed and indicate access from the back of the list. For example -1 means the last node, -2 means the second before last and so on.
Examples

Shows how to add and remove sections in a document.

auto doc = MakeObject<Document>();
auto builder = MakeObject<DocumentBuilder>(doc);
builder->Write(u"Section 1");
builder->InsertBreak(BreakType::SectionBreakNewPage);
builder->Write(u"Section 2");
ASSERT_EQ(u"Section 1\x000c"
u"Section 2",
doc->GetText().Trim());
// Delete the first section from the document.
doc->get_Sections()->RemoveAt(0);
ASSERT_EQ(u"Section 2", doc->GetText().Trim());
// Append a copy of what is now the first section to the end of the document.
int lastSectionIdx = doc->get_Sections()->get_Count() - 1;
SharedPtr<Section> newSection = doc->get_Sections()->idx_get(lastSectionIdx)->Clone();
doc->get_Sections()->Add(newSection);
ASSERT_EQ(u"Section 2\x000c"
u"Section 2",
doc->GetText().Trim());

◆ ToArray()

System::ArrayPtr<System::SharedPtr<Aspose::Words::Node> > Aspose::Words::NodeCollection::ToArray ( )

Copies all nodes from the collection to a new array of nodes.

You should not be adding/removing nodes while iterating over a collection of nodes because it invalidates the iterator and requires refreshes for live collections.

To be able to add/remove nodes during iteration, use this method to copy nodes into a fixed-size array and then iterate over the array.

Returns
An array of nodes.
Examples

Shows how to replace all textbox shapes with image shapes.

auto doc = MakeObject<Document>(MyDir + u"Textboxes in drawing canvas.docx");
ArrayPtr<SharedPtr<Shape>> shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_OfType<SharedPtr<Shape>>()->LINQ_ToArray();
auto isTextBox = [](SharedPtr<Shape> s)
{
return s->get_ShapeType() == ShapeType::TextBox;
};
auto isImage = [](SharedPtr<Shape> s)
{
return s->get_ShapeType() == ShapeType::Image;
};
ASSERT_EQ(3, shapes->LINQ_Count(isTextBox));
ASSERT_EQ(1, shapes->LINQ_Count(isImage));
for (SharedPtr<Shape> shape : shapes)
{
if (shape->get_ShapeType() == ShapeType::TextBox)
{
auto replacementShape = MakeObject<Shape>(doc, ShapeType::Image);
replacementShape->get_ImageData()->SetImage(ImageDir + u"Logo.jpg");
replacementShape->set_Left(shape->get_Left());
replacementShape->set_Top(shape->get_Top());
replacementShape->set_Width(shape->get_Width());
replacementShape->set_Height(shape->get_Height());
replacementShape->set_RelativeHorizontalPosition(shape->get_RelativeHorizontalPosition());
replacementShape->set_RelativeVerticalPosition(shape->get_RelativeVerticalPosition());
replacementShape->set_HorizontalAlignment(shape->get_HorizontalAlignment());
replacementShape->set_VerticalAlignment(shape->get_VerticalAlignment());
replacementShape->set_WrapType(shape->get_WrapType());
replacementShape->set_WrapSide(shape->get_WrapSide());
shape->get_ParentNode()->InsertAfter(replacementShape, shape);
shape->Remove();
}
}
shapes = doc->GetChildNodes(NodeType::Shape, true)->LINQ_OfType<SharedPtr<Shape>>()->LINQ_ToArray();
ASSERT_EQ(0, shapes->LINQ_Count(isTextBox));
ASSERT_EQ(4, shapes->LINQ_Count(isImage));
doc->Save(ArtifactsDir + u"Shape.ReplaceTextboxesWithImages.docx");

◆ Type()

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