Need to add FieldRef to the selection text - Need Help

<w:r>
	<w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
	<w:instrText xml:space="preserve"> REF _Ref100000001 \h </w:instrText>
</w:r>
<w:r>
	<w:fldChar w:fldCharType="separate" />
</w:r>
<w:r>
	<w:t xml:space="preserve">Schedule 1</w:t>
</w:r>
<w:r>
	<w:fldChar w:fldCharType="end" />
</w:r>

I want to create the similar xml structure. Means find “Schedule 1” and add fldchar Start, Seperator and End. How can I acheive this in Aspose

@coderthiyagarajan1980 You could use Find and Replace functionality with IReplacingCallback.

ReplaceAction IReplacingCallback.Replacing(ReplacingArgs args)
{
    bool needtoCheckPreText = !String.IsNullOrEmpty(preText);
    // This is a Run node that contains either the beginning or the complete match.
    Node currentNode = args.MatchNode;
    string FindText = currentNode.Range.Text;
    if (currentNode.Range.Text.Length < args.MatchOffset) return ReplaceAction.Skip;

    Node prevNodeVal = currentNode;
    // 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 (args.MatchOffset > 0)
        currentNode = SplitRun((Aspose.Words.Run)currentNode, args.MatchOffset);

    // 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 = args.Match.Value.Length;
    while (
        (remainingLength > 0) &&
        (currentNode != null) &&
        (currentNode.GetText().Length <= remainingLength))
    {
        runs.Add(currentNode);
        remainingLength = remainingLength - currentNode.GetText().Length;

        prevNodeVal = currentNode;

        // 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((Aspose.Words.Run)currentNode, remainingLength);
        runs.Add(currentNode);
    }

    DocumentBuilder oDocBuild = new DocumentBuilder(args.MatchNode.Document as Document);


    // Check if the replaced text contains a hyperlink
    if (currentNode != null)
    {
        foreach (Field field in currentNode.ParentNode.Range.Fields)
        {
            if (field.Type == FieldType.FieldRef && field.Result.Contains(FindText))
            {
                // Get the text from the field result
                string resultText = field.Result;

                // Remove the field from the document
                field.Remove();

                // Find the first paragraph after the parent node
                Paragraph? para = currentNode.ParentNode as Paragraph;

                // If no paragraph found, create a new paragraph
                if (para == null)
                {
                    para = new Paragraph(currentNode.Document);
                    currentNode.ParentNode.ParentNode.InsertBefore(para, currentNode.ParentNode);
                }

                // Create a new Run node with the resultText
                Run newRun = new Run(currentNode.Document, resultText);

                para.InsertBefore(newRun, currentNode);
            }
        }
        currentNode = currentNode.PreviousSibling;
        if (currentNode.NodeType == NodeType.BookmarkEnd || currentNode.NodeType == NodeType.BookmarkStart)
        {
            currentNode = currentNode.PreviousSibling;
        }
        if (args.MatchOffset > 0 && currentNode.NextSibling.NodeType != NodeType.BookmarkStart && currentNode.NextSibling.NodeType != NodeType.BookmarkEnd)
        {
            currentNode = SplitRun((Aspose.Words.Run)currentNode, args.MatchOffset);
            runs.Clear();
            runs.Add((Aspose.Words.Run)currentNode);
        }
        else
        {
            runs.Clear();
            runs.Add((Aspose.Words.Run)currentNode);
        }
    }

    // Now Add field codes in the sequence

    if (currentNode != null)
    {
        if (needtoCheckPreText && currentNode.PreviousSibling.GetText().Trim().EndsWith(preText) || !needtoCheckPreText)
        {
            oDocBuild.MoveTo(currentNode);

            SelectInsertReferenceType(oDocBuild);

            foreach (Run run in runs)
            {
                if (run.ParentNode != null)
                {
                    run.Remove();
                }
            }
        }
    }
    else
    {
        oDocBuild.MoveTo(prevNodeVal);
    }

    return ReplaceAction.Skip;
}

private void SelectInsertReferenceType(DocumentBuilder oDocBuild)
{
    if (CrossReferenceController.ISReferencedParaListItem)
    {
        FieldRef fieldRef = (FieldRef)oDocBuild.InsertField(FieldType.FieldRef, true);
        fieldRef.BookmarkName = "REF _Ref" + mStartBookmarkNumber + " \\h";
        fieldRef.Update();

        //// Insert the PAGEREF field using InsertField method
        //FieldRef fieldRef = (FieldRef)oDocBuild.InsertField("PAGEREF " + "_Ref" + mStartBookmarkNumber + " \\h", null);
        //// Optionally update the field to display the correct page number
        //fieldRef.Update();

        //// Insert the PAGEREF field using InsertField method
        //// Optionally update the field to display the correct page number
        //// Create a Run node for the field start
        //Run startRun = new Run(oDocBuild.Document);
        //startRun.Text = "";
        //Run fieldStartRun = new Run(oDocBuild.Document, "\u0013");

        //// Create a Run node for the field separator (optional)
        //Run separatorRun = new Run(oDocBuild.Document);
        //separatorRun.Text = "";
        //Run fieldSeparatorRun = new Run(oDocBuild.Document, "\u0014");

        ////Create a bookmark run
        //Run bookmarkRun = new Run(oDocBuild.Document);
        //bookmarkRun.Text = "REF " + "_Ref" + mStartBookmarkNumber + " \\h";

        //// Create a Run node for the field end
        //Run endRun = new Run(oDocBuild.Document);
        //endRun.Text = "";
        //Run fieldEndRun = new Run(oDocBuild.Document, "\u0015");

        //currentNode.ParentNode.InsertBefore(startRun, currentNode);
        //startRun.ParentNode.InsertBefore(fieldStartRun, startRun);
        //currentNode.ParentNode.InsertBefore(bookmarkRun, currentNode);

        //currentNode.ParentNode.InsertBefore(separatorRun, currentNode);
        //separatorRun.ParentNode.InsertBefore(fieldSeparatorRun, separatorRun);
        //currentNode.ParentNode.InsertAfter(endRun, currentNode);
        //endRun.ParentNode.InsertBefore(fieldEndRun, endRun);
    }
    else
    {
        switch (insertReferenceType)
        {
            case "page_number":
                FieldPageRef ReffieldPage = (FieldPageRef)oDocBuild.InsertField(FieldType.FieldPageRef, false);
                ReffieldPage.BookmarkName = "_Ref" + mStartBookmarkNumber;
                ReffieldPage.InsertHyperlink = true;
                ReffieldPage.Update();
                break;
            case "paragraph_number":
            case "paragraph_number_no_context":
            case "paragraph_number_full_context":
            case "above_or_below":
            case "paragraph_text":
                FieldRef Reffield = (FieldRef)oDocBuild.InsertField(FieldType.FieldRef, false);
                Reffield.InsertParagraphNumber = insertReferenceType != "paragraph_text" && insertReferenceType != "above_or_below";
                if (insertReferenceType == "paragraph_number_full_context")
                {
                    Reffield.InsertParagraphNumberInFullContext = true;
                }
                else if (insertReferenceType == "paragraph_number_no_context")
                {
                    Reffield.InsertParagraphNumberInRelativeContext = true;
                }
                if (insertReferenceType == "above_or_below")
                {
                    Reffield.InsertRelativePosition = true;
                }
                Reffield.BookmarkName = "_Ref" + mStartBookmarkNumber;
                Reffield.InsertHyperlink = true;
                Reffield.Update();
                break;
        }
    }
}

Yes correct. I added the IReplacingCallback function only, but not able to add fldChar Start, Seperator and End. How can I acheive this?

@coderthiyagarajan1980 You could use the following code to insert fldChar Start, Seperator and fldChar End:

Document doc = new Document("test.docx");
FindReplaceOptions options = new FindReplaceOptions(new ReplaceCallback());
doc.Range.Replace("Schedule 1", "", options);

class ReplaceCallback : IReplacingCallback
{
    public ReplaceAction Replacing(ReplacingArgs e)
    {
        Document doc = (Document)e.MatchNode.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);

        // This array is used to store all nodes of the match for further deleting.
        List<Run> runs = new List<Run>();

        // 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((Run)currentNode);
            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((Run)currentNode);
        }

        // Insert field after text
        DocumentBuilder builder = new DocumentBuilder(doc);
        builder.MoveTo(runs[runs.Count - 1]);
        builder.InsertField("REF _Ref100000001 \\h", "Schedule 1");
        
        // Remove text
        runs.ForEach(r => r.Remove());

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }
    
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run) run.Clone(true);
        run.ParentNode.InsertAfter(afterRun, run);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring((0), (0) + (position));
        return afterRun;
    }
}

No, my requirement is to retain the text “Schedule 1” and then create cross refererence link. But the above code replaces the “Schedule 1.”

@coderthiyagarajan1980 The text “Schedule 1” is preserved inside the field. The output is like you described in the first post (see Replace.png (16.6 KB)). If you want to get different result please attach the desired output.