Word Replacement Problem

Hi,

I have a word file.I am replacing tags with real values.But it has some problems
For examle I have a tag like when I raplace this tag with its real value “00H-015”
it seems as 00 H - 015 DOC.I attached original file could you please check it.My code like this;

``cs
ReplaceWithEvaluator(wordDoc, “”, “00H-015”, withLang);
public static void ReplaceWithEvaluator(Aspose.Words.Document wordDoc, string OldValue, string NewValue, bool withLanguage)
{
// ReplaceEval myReplaceEval = new ReplaceEval();
// myReplaceEval.ReplaceText = NewValue;
ReplaceEval.ReplaceText = NewValue.Replace("\n", “”);
// wordDoc.Range.Replace( new System.Text.RegularExpressions.Regex(@"<" + OldValue + @">"), ReplaceEval.TextEvaluator, false);
ReplaceEval.WithLang = withLanguage;
wordDoc.Range.Replace(
new System.Text.RegularExpressions.Regex(@"<" + OldValue + @">"), new ReplaceEval(), false);
}
public class ReplaceEval : IReplacingCallback
{
private static string replaceText = “”;
private static bool withLang = false;
public static string ReplaceText
{

    get { return replaceText; }
    set { replaceText = value; }

}
public static bool WithLang
{

    get { return withLang; }
    set { withLang = value; }
}
public ReplaceAction Replacing(Aspose.Words.ReplacingArgs e)
{
    DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Aspose.Words.Document);
    // builder.MoveTo(e.MatchNode);
    ////e.Replacement = replaceText;
    // if (withLang)
    // builder.Font.Bidi = true;
    // builder.Write(replaceText);
    // e.Replacement = "";
    // return ReplaceAction.Replace;
    Node currentNode = e.MatchNode;
    if (e.MatchOffset > 0)
        currentNode = SplitRun((Run)currentNode, e.MatchOffset);
    ArrayList runs = new ArrayList();
    int remainingLength = e.Match.Value.Length;
    while (
        (remainingLength > 0) &&
        (currentNode != null) &&
        (currentNode.GetText().Length <= remainingLength))
    {
        runs.Add(currentNode);
        remainingLength = remainingLength - currentNode.GetText().Length;
        do
        {
            currentNode = currentNode.NextSibling;
        }
        while ((currentNode != null) && (currentNode.NodeType != NodeType.Run));
    }
    if ((currentNode != null) && (remainingLength > 0))
    {
        SplitRun((Run)currentNode, remainingLength);
        runs.Add(currentNode);
    }
    if (runs.Count > 0)
    {
        builder.MoveTo((Run)runs[0]);
        Run newrun = new Run(e.MatchNode.Document as Aspose.Words.Document, replaceText);
        newrun.Font.Size = ((Run)runs[0]).Font.Size;
        newrun.Font.Name = ((Run)runs[0]).Font.Name;
        newrun.Font.Bold = ((Run)runs[0]).Font.Bold;

        if (withLang)
            newrun.Font.Bidi = true;
        builder.InsertNode(newrun);
        foreach (Run run in runs)
        {
            run.Remove();
        }
    }
    return ReplaceAction.Skip;
}
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;
}

}

Hi Ahmet,

Thanks for your inquiry. The problem occurs because the parent Paragraph of the matching node contains a SmartTag node. You may want to adjust your logic to handle those SmartTag nodes for example as follows:

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);
    foreach(SmartTag tag in run.ParentNode.GetChildNodes(NodeType.SmartTag, true))
        tag.Remove();
    return afterRun;
}

I hope, this helps.

Best Regards,

Hi,
This file belogs to our customer.Do I see another problem in the future,if I remove smart tags?

Hi Ahmet,

Thanks for your inquiry. Well, it depends on your implementation of IReplacingCallback interface. You need to be sure that you handle all possible cases in the class implementing this interface. I think, in your case, the code from second example in this article should work fine.

Best Regards,

We had another problems in the past so, your employee sent me this codes and my problem resolved but now we have this problem.What can I do?

Hi Ahmet,

Thanks for the additional information. We are checking with your scenario and will get back to you soon.

Best Regards,

Hi Ahmet,

Please accept my apologies for your inconvenience.

For this scenario, I have modified the ReplaceEval class and have highlighted the modification. Please use the following modified ReplaceEval class. Please feel free to ask if you have any question about Aspose.Words, we will be happy to help you.

public void ReplaceWithEvaluator(Aspose.Words.Document wordDoc, string OldValue, string NewValue, bool withLanguage)
{
    ReplaceEval.ReplaceText = NewValue.Replace("\n", "");
    ReplaceEval.OldValue = OldValue;
    wordDoc.Range.Replace(new System.Text.RegularExpressions.Regex(@"\<" + OldValue + @"\>"), new ReplaceEval(), false);
    wordDoc.Save(MyDir + @"AsposeOut.doc");
}
public class ReplaceEval : IReplacingCallback
{
    private static string oldValue;
    public static string OldValue
    {

        get { return oldValue; }
        set { oldValue = value; }

    }
    private static string replaceText = "";
    private static bool withLang = false;
    public static string ReplaceText
    {

        get { return replaceText; }
        set { replaceText = value; }

    }
    public static bool WithLang
    {

        get { return withLang; }
        set { withLang = value; }

    }
    public ReplaceAction Replacing(Aspose.Words.ReplacingArgs e)
    {
        DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Aspose.Words.Document);
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;
        // 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 tags = new ArrayList();
        if (currentNode.ParentNode.IsComposite)
        {
            foreach (SmartTag tag in currentNode.ParentNode.GetChildNodes(NodeType.SmartTag, true))
            {
                foreach (Run run in tag.GetChildNodes(NodeType.Run, true))
                {
                    if (OldValue.Contains(run.Text.Trim()))
                        tags.Add(run);
                }
            }
        }
        // This array is used to store all nodes of the match for further highlighting.
        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);
        }
        if (runs.Count > 0)
        {
            builder.MoveTo((Run)runs[0]);
            Run newrun = new Run(e.MatchNode.Document as Aspose.Words.Document, replaceText);
            newrun.Font.Size = ((Run)runs[0]).Font.Size;
            newrun.Font.Name = ((Run)runs[0]).Font.Name;

            if (withLang)
                newrun.Font.Bidi = true;
            builder.InsertNode(newrun);
            foreach (Run run in runs)
            {
                run.Remove();
            }
            foreach (Run run in tags)
            {
                run.Remove();
            }
        }
        return ReplaceAction.Skip;
    }
}

Thank you for your attention.My problem is resolved

Hi Ahmet,

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