Replace/Remove ParagraphBreaks

I am currently doing a find-replace operation using the IReplacingCallback interface (accomplished with your kind assistance!), to find a text string and then replace it with the text for a rather complex IncludePicture-MergeField set of fields. Relevant code is as follows:

var findReplaceOptions = new FindReplaceOptions
{
ReplacingCallback = new FindAndReplaceClientLogos()
};

wordTemplateDocument.Range.Replace(“CLIENTLOGO”, string.Empty, findReplaceOptions);

internal class FindAndReplaceClientLogos : IReplacingCallback
{
ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
{
Node currentNode = e.MatchNode;

        DocumentBuilder docBuilder = new DocumentBuilder(e.MatchNode.Document as Document);

        docBuilder.MoveTo(currentNode);

        FieldIf fieldIf = (FieldIf)docBuilder.InsertField(FieldType.FieldIf, false);
        docBuilder.MoveTo(fieldIf.Separator);

        FieldIncludePicture fieldPic = (FieldIncludePicture)docBuilder.InsertField(FieldType.FieldIncludePicture, false);
        fieldPic.ResizeHorizontally = true;
        fieldPic.ResizeVertically = true;

        docBuilder.MoveTo(fieldPic.Separator);
        FieldIf fieldIf2 = (FieldIf)docBuilder.InsertField(FieldType.FieldIf, false);

        docBuilder.MoveTo(fieldIf2.Separator);
        docBuilder.Write(" TRUE ");

        FieldMergeField fieldMerge = (FieldMergeField)docBuilder.InsertField(FieldType.FieldMergeField, false);
        fieldMerge.FieldName = "ClientLogoFilename";

        docBuilder.MoveTo(fieldIf.Separator);

        FieldIncludePicture fieldPic2 = (FieldIncludePicture)docBuilder.InsertField(FieldType.FieldIncludePicture, false);
        fieldPic2.ResizeHorizontally = true;
        fieldPic2.ResizeVertically = true;

        docBuilder.MoveTo(fieldPic2.Separator);

        FieldIf fieldIf3 = (FieldIf)docBuilder.InsertField(FieldType.FieldIf, false);

        docBuilder.MoveTo(fieldIf3.Separator);
        docBuilder.Write(" TRUE ");

        FieldMergeField fieldMerge2 = (FieldMergeField)docBuilder.InsertField(FieldType.FieldMergeField, false);
        fieldMerge2.FieldName = fieldMerge.FieldName;

        fieldIf3.Update();
        fieldMerge2.Update();
        fieldPic2.Update();
        fieldIf2.Update();
        fieldMerge.Update();
        fieldPic.Update();
        fieldIf.Update();

        // remove the old "CLIENTLOGO" node (that we're replacing)
        currentNode.Remove();

        // signal to the replace engine to do nothing because we have already done all that we wanted
        return ReplaceAction.Skip;
    }
}

DynamicImage-Textbox-Aspose-Example-ClientLogo.zip (24.1 KB)

This works great but I am curious how hard it would be to find any ParagraphBreaks surrounding the text I’m searching for (I thought they were LineBreaks but debugging my code and looking at the Node’s Range, shows they’re ParagraphBreaks) and remove them or replace them with string.Empty or similar.

I did some searching in the forum and haven’t really found anything and haven’t found a way myself. I’ve attached an example Word document that’s basically what I’m working with.

Any help would be greatly appreciated. Thanks so much!

@Robert343,

Thanks for your inquiry. Please check the following code snippet to remove the line break and empty paragraph. Hope this helps you.

ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
{
    Node currentNode = e.MatchNode;

    if (currentNode.PreviousSibling != null && currentNode.PreviousSibling.GetText().Equals(ControlChar.LineBreak))
        currentNode.PreviousSibling.Remove();

    if (currentNode.ParentNode.NextSibling != null && currentNode.ParentNode.NextSibling.ToString(SaveFormat.Text).Trim().Equals(""))
        currentNode.ParentNode.NextSibling.Remove();

    DocumentBuilder docBuilder = new DocumentBuilder(e.MatchNode.Document as Document);

    docBuilder.MoveTo(currentNode);

Thank you very much for the prompt reply.

I copied your provided code but it doesn’t seem to work. I added debug points and noticed that while the second “if” statement (checking ParentNode.NextSibling and then removing it) gets hit and ParentNode.NextSibling.Remove(); is called, that still does not seem to remove that node. After that .Remove() method is called, when I inspected the ParentNode’s .NextSibling property, it was still there (as a Paragraph).

Here’s a pic when debugging, with the .NextSibling property pinned (and showing it still is a Paragraph):
aspose-words-remove-parabreaks.png (2.5 KB)

Any ideas? Thank you.

EDIT: I am using a slightly different (longer, 4 pages) template for my work and when I tried using the simple template I originally attached, your code did indeed remove the .NextSibling. I’m not sure why it’s not occurring when using my template, and I am hesitant to upload it since it is for my work and may contain private data. I even chopped it down to a single page so it’s nearly identical to the one I originally attached, and the code still isn’t working. Is there a way I could give you my template privately?

@Robert343,

Thanks for your inquiry. To remove the empty paragraph, you need to use Paragraph.Remove method. The line break is imported into Run node. You can use Range.Replace method to replace the line break with empty string as shown below or remove the Run node.

Paragraph.Range.Replace(ControlChar.LineBreak, “”, new FindReplaceOptions())

We have made this forum thread as private. Now, only you and Aspose staff members can access this forum thread. Please ZIP and attach your input and expected output Word documents here for our reference. We will then provide you more information about your query .

Thank you for the reply and for making the thread private.

I tried replacing the Paragraph’s LineBreaks with string.Empty, via the Range, but to no avail. I put this line (given by you in your last reply) in the second of those two “if” statements:

if (currentNode.ParentNode.NextSibling != null)
            {
                var billy = currentNode.ParentNode.NextSibling.ToString(SaveFormat.Text).Trim();

                if (billy.Equals(string.Empty))
                {
                    currentNode.ParentNode.NextSibling.Range.Replace(ControlChar.LineBreak, string.Empty, new FindReplaceOptions());
                    //currentNode.ParentNode.NextSibling.Remove();
                }
            }

I’m not sure if that was the correct place to do it but it seemed like it.

Since you were able to make the thread private, I have attached the full Word document I’ve been working with.

The expected output is any line breaks/newlines/etc removed from the Textbox containing the “CLIENTLOGO” text near the bottom of the second page. Just the “CLIENTLOGO” text should remain in the Textbox.

Thank you very much!

ReplaceLineBreaksFullTemplate.zip (19.5 KB)

@Robert343,

Thanks for sharing the detail. In your case, the “CLIENTLOGO” is inside frame or shape node. Please use the following code snippet to remove empty paragraph nodes.

Node currentNode = e.MatchNode;

ArrayList removeParagraphs = new ArrayList();
if (currentNode.ParentNode.NextSibling != null)
{
    Paragraph para = (Paragraph)currentNode.ParentNode.NextSibling;
    //If the CLIENTLOGO is inside Frame or Shape
    while (para != null && para.ToString(SaveFormat.Text).Trim() == "" && (para.FrameFormat.IsFrame || para.GetAncestor(NodeType.Shape) != null))
    {
        if (para.NextSibling != null && para.NextSibling.NodeType == NodeType.Paragraph)
        {
            removeParagraphs.Add(para);
            para = (Paragraph)para.NextSibling;
        }
        else
            break;
    }
}

if (currentNode.ParentNode.PreviousSibling != null)
{
    Paragraph para = (Paragraph)currentNode.ParentNode.PreviousSibling;
    //If the CLIENTLOGO is inside Frame or Shape
    while (para != null && para.ToString(SaveFormat.Text).Trim() == "" && (para.FrameFormat.IsFrame || para.GetAncestor(NodeType.Shape) != null))
    {
        if (para.PreviousSibling != null && para.PreviousSibling.NodeType == NodeType.Paragraph)
        {
            removeParagraphs.Add(para);
            para = (Paragraph)para.PreviousSibling;
        }
        else
            break;
    }
}
foreach (Node node in removeParagraphs)
{
    node.Remove();
}

currentNode.Range.Replace(ControlChar.LineBreak, "", new FindReplaceOptions());

DocumentBuilder docBuilder = new DocumentBuilder(e.MatchNode.Document as Document);

docBuilder.MoveTo(currentNode);