Find and replace html content work not well

Hello Aspose,

I have a file template docx VN_BemerkungBugWrongPosition.zip (9.4 KB)

And I create a function to replace placeholder("[@@CASE_BEMERKUNGALLGEMEIN@@]") by a string (I using simple text but my project is html content). I using code like your API:

static void RelacePlaceHolderByHtmlContent()
{
Document doc = new Document(dataDir + fileName);
FindReplaceOptions options = new FindReplaceOptions();
options.ReplacingCallback = new ReplaceWithHtmlEvaluator(options, “This is replaced inline and wrong position”);
doc.Range.Replace("[@@CASE_BEMERKUNGALLGEMEIN@@]", string.Empty, options);
string pathSave = dataDir + “VN_BemerkungBugWrongPosition_out.docx”;
if (File.Exists(pathSave)) { File.Delete(pathSave); }
doc.Save(pathSave);
Console.Write(“Replace Success”);
Console.ReadKey();
}

public class ReplaceWithHtmlEvaluator : IReplacingCallback
{
internal ReplaceWithHtmlEvaluator(FindReplaceOptions options, string text)
{
mOptions = options;
mText = text;
}
ReplaceAction IReplacingCallback.Replacing(ReplacingArgs args)
{
DocumentBuilder builder = new DocumentBuilder((Document)args.MatchNode.Document);
builder.MoveTo(args.MatchNode);
builder.InsertHtml(mText);
args.Replacement = “”;
return ReplaceAction.Replace;
}

        private readonly FindReplaceOptions mOptions;
        private readonly string mText;
    }

The File docx I have attached in “VN_BemerkungBugWrongPosition.zip”. Please see in detail.
I found some information from your API:
"///


/// NOTE: This is a simplistic method that will only work well when the match
/// starts at the beginning of a run.
///
"

So How can I replace in right position in this case?

Thank you very much!

@nguyenhungkloon

Could you please share the issue that you are facing while replacing text with HTML along with following resources?

  • Your input HTML.
  • Please attach the output Word file that shows the undesired behavior.
  • Please attach the expected output Word file that shows the desired behavior.

As soon as you get these pieces of information ready, we will start investigation into your issue and provide you more information. Thanks for your cooperation.

PS: To attach these resources, please zip and upload them.

Dears,

Now I have attach a small demo project with some information, please see in file: File send APSOE.zip (5.6 MB)

  1. Input Html: “This is replaced inline and wrong position”
  2. output word file: VN_BemerkungBugWrongPosition_out.docx. See detail in Bin folder.
  3. expected word file: VN_BemerkungBugWrongPosition_expected_out.docx . See detail in Bin folder.

I also create 2 method to compare:

  • RelacePlaceHolderByContent(): will be give us right position.

  • RelacePlaceHolderByHtmlContent(): give us wrong position.

Please see in project.

My question is How can I replace html content with same position with normal text?

Thank you very much!

@nguyenhungkloon

Please use the following ReplaceWithHtmlEvaluator code to get the desired output. Hope this helps you.

public class ReplaceWithHtmlEvaluator : IReplacingCallback
{
    internal ReplaceWithHtmlEvaluator(FindReplaceOptions options, string text)
    {
        mOptions = options;
        mText = text;
    }
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {

        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;

        if (builder == null)
            builder = new DocumentBuilder((Document)currentNode.Document);

        // The first (and may be the only) run can contain text before the match, 
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);

        ArrayList runs = new ArrayList();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.Match.Value.Length;
        while (
            (remainingLength > 0) &&
            (currentNode != null) &&
            (currentNode.GetText().Length <= remainingLength))
        {
            runs.Add(currentNode);
            remainingLength = remainingLength - currentNode.GetText().Length;

            // Select the next Run node. 
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.NextSibling;
            }
            while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
        }

        // Split the last run that contains the match if there is any text left.
        if ((currentNode != null) && (remainingLength > 0))
        {
            SplitRun((Run)currentNode, remainingLength);
            runs.Add(currentNode);
        }

        Run run = (Run)runs[0];
        builder.MoveTo(run);
        builder.InsertHtml(mText);

        foreach (Node node in runs)
        {
            node.Remove();
        }

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

    /// <summary>
    /// Splits text of the specified run into two runs.
    /// Inserts the new run just after the specified run.
    /// </summary>
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run)run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
    
    DocumentBuilder builder;
    private readonly FindReplaceOptions mOptions;
    private readonly string mText;
}

Thank
tahir.manzoor
,

I use your source code and it work.

@nguyenhungkloon

Thanks for your feedback. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.