Remove everyting between two formfields


#1

How can I remove everything between two formfields, let say form field with name “start” and “end”. Between those two can be text, other formfields, tables…any object that starts and ends between this two formfields. And in the end i need to remove those two “start” and “end” formfields as well.
I did wrote some code, but wen a started removing nodes, i screwed nodeCollection for formfields.

Professionals please help! :slight_smile:


#2

Yes, node removal while iterating through document node collection is generally a bad idea.

Try to put nodes that are to be removed into separate collection, e.g ArrayList and then remove them in a separate loop.

Also please mind that although there is a FormField node in node types this node is only a part of the FormField structure. Please use DocumentExplorer source code demo to get a quick impression on how formfield is represented in Aspose.Words document object model.

The DocumentExplorer demo can be found in C:\Program Files\Aspose\Aspose.Words\Demos\DocumentExplorer directory after Aspose.Words evaluation pack installation.

Best regards,


#3

I created a code that works (removes anything between two formfields - they can also be nested and if there is a data for form field every thing between a start and end formfield is removed).

I have two more problems to solve:

  1. Between two formfields can be anything (other formfields, tables, formfield starts in one paragraph end ends in another). Thats not the problem, becuase i remove just child nodes of all paragraphs between them. What if i have this optional part in a table cell? Then the parent is Table and not Paragraph. Object Node does not support ChildNodes method. How can I then select all childs of a type, which i do not know which type is it (Paragraph, Table,…). See the code marked with Red
  2. I noticed that some times each FormField has its own bookmark starting before fieldStart and ending BEFORE field end. Some times there is a bookmark start and the bookmark end in some other field. Some times there was a bookmark start long before current field and end in this field. And sometimes there is no bookmark at all. How strict is a word document format and where can I find all the possible combinations of formfields and bookmarks and how to replecate each combination?
and here is a code. Do not be afraid Smile [:)]
//_opt_X start an optional parts, _opte_X ends an optional part
bool nodeFound = false;
ArrayList formFieldsToRemove = new ArrayList();
ArrayList nodesToDelete = new ArrayList();


foreach (FormField FF in doc.Range.FormFields)
{

string nameFieldFULL = FF.Name.ToUpper();
if (nameFieldFULL.StartsWith(“OPT”))
{
//ok we have a starting formfield

string endName = nameFieldFULL.Insert(4, “E”); //end name
nodeFound = false;

for (Node nodePar = FF.ParentNode; nodePar != null; nodePar = nodePar.NextSibling)
{
Node node = ((Paragraph)nodePar).GetChild(NodeType.Any, 0, false);
for (; node != null; node = node.NextSibling)
{
if (node.NodeType == NodeType.FormField)
{
if (((FormField)node).Name.ToUpper().CompareTo(endName) == 0)
{
nodeFound = true; //ending formfield found
break;
}
}
}
}

string nameFiledTemp = fieldName(FF.Name).ToUpper();
if (nodeFound == true && general.ContainsKey(nameFiledTemp)) // there is an ending formfield after starting formfield
{

Node node = FF;
do
{
node = node.NextSibling;
} while (node != null && node.NodeType != NodeType.BookmarkEnd);

//now “delete” to the end formfield

bool overLaps;
overLaps = true;
bool first = true;
bool endFound = false;
bool nodeFoundIX = false;
for (Node nodePar = FF.ParentNode; nodePar != null; nodePar = nodePar.NextSibling)
{

Node nodex = ((Paragraph)nodePar).GetChild(NodeType.Any, 0, false);
for (; nodex != null; nodex = nodex.NextSibling)
{
if (first == true)
nodex = FF; //formfield is not nessecerly a first element
first = false;

if (!nodesToDelete.Contains(nodex) && endFound==true) //we start deleting when we are on a end of a starting formfield
{ //there can be overlaping
nodesToDelete.Add(nodex);
overLaps = false;
}

if ((nodex.NodeType == NodeType.FieldEnd && nodex.NextSibling.NodeType != NodeType.BookmarkEnd) || nodex.NodeType == NodeType.BookmarkEnd)
{
endFound = true;
}
if (nodex.NodeType == NodeType.FormField)
{
if (((FormField)nodex).Name.ToUpper().CompareTo(endName) == 0)
{
//ok, ending formfield found
nodeFoundIX = true;
break;
}
}
}
if (nodeFoundIX == true) break;
}

//we went a little bit too far, remove that “half” of an ending formfield
Node curNode;
if (!overLaps) //if current node exists in arraylist, do not add it again
{
while (nodesToDelete.Count > 0)
{
curNode = (Node)nodesToDelete[nodesToDelete.Count - 1];
nodesToDelete.RemoveAt(nodesToDelete.Count - 1);
if (curNode.NodeType == NodeType.FieldStart) // ok, done
break;


}
}

}
}
}//endforeach formfield

//now we can delete nodes
while (nodesToDelete.Count > 0)
{
Node tempNode2 = (Node)nodesToDelete[0];
nodesToDelete.RemoveAt(0);
tempNode2.Remove();
}

#4

If the node has child nodes than it is also a CompositeNode (inheritor of Node). You can check if the node is CompositeNode and if it is cast it and use CompositeNode methods for retrieving child nodes:

if (node is CompositeNode)

CompositeNode compositeNode = (CompositeNode)node;

Bookmarks are inserted automatically when formfields are inserted in MS Word. Sometimes they bookmark start is placed befor field start sometimes after. I think it depenmds on the version of MS Word. These bookmarks can be removed afterwards. I have seen several user templates where formfields had no bookmarks for them. Also, other bookmarks, inserted explicitly by user can occur anywhere in the document.

Best regards,