hi,
I am using the following code to delete text in a document using a start and finish position. I also need to delete all content between these two positions including sections breaks tables etc. How do I do this?
private void TextDeleteByPosition(Document Doc, int startPosition, int length)
{
int currentPosition = 0;
NodeCollection runs = Doc.GetChildNodes(NodeType.Run, true);
foreach (Run run in runs)
{
//Set current position
currentPosition += run.Text.Length;
if (currentPosition <= startPosition)
{
continue;
}
else
{
int tmpStart = 0;
int tmpLenth = 0;
//Calculate position in current run
if (currentPosition - run.Text.Length < startPosition)
{
tmpStart = startPosition - (currentPosition - run.Text.Length);
}
//Calculate lenth of sub string that should be removed from current run
if (run.Text.Length - tmpStart >= length)
{
tmpLenth = length;
}
else
{
tmpLenth = run.Text.Length - tmpStart;
}
//Reset lenth
length = length - tmpLenth;
if (tmpLenth == 0)
break;
//Remove substring from current run
run.Text = run.Text.Remove(tmpStart, tmpLenth);
string t = run.ParentParagraph.Range.Text;
if (run.ParentParagraph.Range.Text == "" || run.ParentParagraph.Range.Text == "\r")
{
ndCol.Add(run.ParentParagraph);
}
}
}
}
Hello!
Thank you for your interesting question.
First of all I see that position in your code is the number of character from the start of the document. And no other document elements count. Aspose.Words document model is hierarchical, not sequential. Run objects can occur on the different levels of hierarchy, in different sections and stories. (Story is one of the following: section body, any header or footer, text box in a shape.) When you fetch child nodes of some type like this:
You map a part of hierarchical structure to a simple sequence. What should we do with this sequence to affect hierarchy? It’s a very difficult question. Recently I improved code that gathers text from a given bookmark. This needed non-trivial traversal approach. But gathering text doesn’t modify document structure. Deletion is much more difficult. You will note that some nodes have to be partially deleted, some deletions are very questionable. Imagine that start position is inside a table and end position is outside. What do you expect from your algorithm to do with the table? There are many such questions.
Please attach a test document and show us some typical cases you want to cover. We’ll try to help solving these specific cases.
Regards,
I have the start position and the length so have been using the code above, but it is not deleting the non text content. I tried using the range.replace and a replace evaluator but it does not work because of special characters in the content. Bookmarks don’t seem to work properly either because it is in an ExecuteWithRegions mailmerge.
Thank you for additional information. I think using bookmarks is the best way to do what you need. However, the problem with bookmark is that document cannot contain few bookmarks with the same name. However, after performing mail merge such situation might occur. That is why you should rename bookmarks right after performing mail merge. I created simple example for you and attached output document.
//Create dummy datasource
DataTable trustee = new DataTable("Trustee");
trustee.Columns.Add("Trustee_Type");
trustee.Columns.Add("Directors");
trustee.Columns.Add("Company");
trustee.Columns.Add("trustee");
trustee.Columns.Add("Trustee_Name");
trustee.Columns.Add("Trustee_ACN");
//Add few rows to our datatable
trustee.Rows.Add(new object[] { "Trustee_Type", "Directors", "Company", "trustee", "Trustee_Name", "Trustee_ACN" });
trustee.Rows.Add(new object[] { "Trustee_Type", "Directors", "Company", "trustee", "Trustee_Name", "Trustee_ACN" });
trustee.Rows.Add(new object[] { "Trustee_Type", "Directors", "Company", "trustee", "Trustee_Name", "Trustee_ACN" });
trustee.Rows.Add(new object[] { "Trustee_Type", "Directors", "Company", "trustee", "Trustee_Name", "Trustee_ACN" });
//Open template
Document doc = new Document(@"Test025\Signature_Box.doc");
//Execute mail merge with regions
doc.MailMerge.ExecuteWithRegions(trustee);
//Document cannot contain few bookmarks with the same name.
//But after performing mail merge duplicates can occur, so we should remane bookmarks with same names
int bkConter = 0;
ArrayList bkList = new ArrayList();
foreach (Bookmark bk in doc.Range.Bookmarks)
{
//Name of bookmark will contain name of original bookmark and index of the record
string bkName = string.Format("{0}_{1}", bk.Name, bkConter);
while (bkList.Contains(bkName))
{
bkConter++;
bkName = string.Format("{0}_{1}", bk.Name, bkConter);
}
//Set name of bookmark
bk.Name = bkName;
bkList.Add(bk.Name);
}
//Save output document
doc.Save(@"Test025\out.doc");
Now, you can just remove content inside bookmark and you do not need to remove content based on start and end position. As Viktor stated “Aspose.Words document model is hierarchical, not sequential.” So removing content from the document using index and length of the text is not very good idea.
To remove content inside bookmark you can use very simple code like the following:
doc.Range.Bookmarks["mybk"].Text = string.Empty;
Best regards.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
Enables storage, such as cookies, related to analytics.
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.
Sets consent for personalized advertising.
Cookie Notice
To provide you with the best experience, we use cookies for personalization, analytics, and ads. By using our site, you agree to our cookie policy.
More info
Enables storage, such as cookies, related to analytics.
Enables storage, such as cookies, related to advertising.
Sets consent for sending user data to Google for online advertising purposes.