Find and replace text marked by comment

how do you find and replace text (range) that has been marked with comment? do you have sample code for this? the https://docs.aspose.com/words/java/extract-selected-content-between-nodes/ sample only shown how to read and remove comment (but not the text).

Hi, Is possible if i can text in document which has comment?

Hello
Thanks for your inquiry. Please see the following link to find the code which will allow you to get “commented text”:
https://forum.aspose.com/t/get-comment-range-start-and-end/58365
Best regards,

Are there any .net code to find “Commented Text”. There are not classes CommentRangeStart and CommentRangeEnd in Aspose.Word for Dot Net

Hello
Thanks for your request. It seems you are using an old version of Aspose.Words. The latest version of Aspose.Words is 10.2.0; you can download this version from here:
https://releases.aspose.com/words/net
Best regards,

Thank you for your answer

It seems that the nested comments are not reading correctly, especially nested comments. Per the www.cybervn.com/aspose/asposeCommentIssue00.png, the comment J10 does contains value, but aspose control doesn’t seem to sees it. and for comment J26 (attorneyIsLegislator), it shown incorrect order/index and doesnot contains any value. The template and code using for this is www.cybervn.com/aspose/ReadComment.zip - Thanks

Hello
Thanks for your request. Please try using the following code:

Document doc = new Document("C:\Temp\TestFile1.docx");
// Get all comments from the document.
Node[] comments = doc.GetChildNodes(NodeType.Comment, true).ToArray();
Dictionary<Int32, String> commentedTexts = GetCommentedText(doc);
// Loop throught all comments
foreach (Node commemtNode in comments)
{
    Comment comment = (Comment)commemtNode;
    Console.WriteLine("COMMENTED TEXT: {0}\nCOMMENT: {1}\n\n", commentedTexts[comment.Id], comment.ToTxt());
}
private static Dictionary<Int32, String> GetCommentedText(Document doc)
{
    Dictionary<Int32, String> commentedTexts = new Dictionary<Int32, String>();
    CommentedTextFinder finder = new CommentedTextFinder(commentedTexts);
    doc.Accept(finder);
    return commentedTexts;
}
private class CommentedTextFinder : DocumentVisitor
{
    public CommentedTextFinder(Dictionary<Int32, String> commentedTexts)
    {
        mActiveComments = new Dictionary<int, StringBuilder>();
        mCommentedTexts = commentedTexts;
    }
    // /
    // / Called when a Run node is encountered in the document.
    // /
    public override VisitorAction VisitRun(Run run)
    {
        // Exclude Comment node
        if (run.GetAncestor(NodeType.Comment) == null)
            AppendText(run.GetText());
        // Let the visitor continue visiting other nodes.
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a Paragraph node is ended in the document.
    // /
    public override VisitorAction VisitParagraphEnd(Paragraph paragraph)
    {
        // When outputting to plain text we output Cr+Lf characters.
        if (paragraph.GetAncestor(NodeType.Comment) == null)
            AppendText(ControlChar.CrLf);
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeStart(CommentRangeStart commentRangeStart)
    {
        mActiveComments.Add(commentRangeStart.Id, new StringBuilder());
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeEnd(CommentRangeEnd commentRangeEnd)
    {
        // Save commented text in Dictionary.
        mCommentedTexts.Add(commentRangeEnd.Id, mActiveComments[commentRangeEnd.Id].ToString());
        mActiveComments.Remove(commentRangeEnd.Id);
        return VisitorAction.Continue;
    }
    // /
    // / Adds text to the current output. Honours the enabled/disabled output flag.
    // /
    private void AppendText(String text)
    {
        foreach (KeyValuePair<int, StringBuilder> activeComment in mActiveComments)
        {
            activeComment.Value.Append(text);
        }
    }
    private Dictionary<Int32, String> mCommentedTexts;
    private Dictionary<Int32, StringBuilder> mActiveComments;
}

Best regards,

How do you replace the text (document content) that surround by the comment? i.e. for the comments J15 & J16 in the www.cybervn.com/jd00.png, I just want to find the text "in " and replace it with the “” (blank) for J15 only, but it also replace the "in " of the "within " of J16.

Hello
Thanks for your inquiry. Could you please show me the code which you are using to replace “commented text” or attach sample application, which will allow me to reproduce the problem? I will check the problem and try to help you.
Best regards,

Hi, I send you my code to read and replace commented text

class Program
{
    static void Main(string[] args)
    {
        // The sample infrastructure.
        string exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        string dataDir = Path.GetFullPath(Path.Combine(exeDir, @"Data"));
        // Open the document.
        Document doc = new Document(dataDir + "TestFile.docx");
        Dictionary<int, String> commentedTexts = GetCommentedText(doc);
        // Collect all comments in the document which are contain key "willBeInSession" to replace by empty text
        IList comments = ExtractComments(doc, "willBeInSession");
        foreach (Comment comment in comments)
        {
            Console.WriteLine(string.Format("{0}: {1}", comment.Id, commentedTexts[comment.Id]));
            doc.Range.Replace(commentedTexts[comment.Id], "", false, false);
        }
        // Collect all comments in the document which are contain key "client" to replace by empty text
        comments = ExtractComments(doc, "client");
        foreach (Comment comment in comments)
        {
            Console.WriteLine(string.Format("{0}: {1}", comment.Id, commentedTexts[comment.Id]));
            if(comment.ToTxt().Contains("Single"))
                doc.Range.Replace(commentedTexts[comment.Id], "", false, false);
        }
        // Collect all comments in the document which are contain key "attorney" to replace by empty text
        comments = ExtractComments(doc, "attorney");
        foreach (Comment comment in comments)
        {
            Console.WriteLine(string.Format("{0}: {1}", comment.Id, commentedTexts[comment.Id]));
            if (comment.ToTxt().Contains("Single"))
                doc.Range.Replace(commentedTexts[comment.Id], "", false, false);
        }
        RemoveComments(doc);
        doc.Save(dataDir + "TestFileOut.docx");
    }
    static IList ExtractComments(Document doc, string name)
    {
        IList resultComments = new List();
        // Collect all comments in the document
        NodeCollection comments = doc.GetChildNodes(NodeType.Comment, true);
        // Look through all comments and gather information about those written by the authorName author.
        foreach (Comment comment in comments)
        {
            if (comment.ToTxt().Contains(name))
            {
                resultComments.Add(comment);
            }
        }
        return resultComments;
    }
    // ExEnd
    /// The source document.
    /// The name of the comment’s author.
    // ExStart
    // ExId:ProcessComments_Remove_Author
    // ExSummary:Removes comments by the specified author.
    static void RemoveComments(Document doc)
    {
        // Collect all comments in the document
        NodeCollection comments = doc.GetChildNodes(NodeType.Comment, true);
        // Look through all comments and remove those written by the authorName author.
        for (int i = comments.Count - 1; i >= 0; i–)
        {
            Comment comment = (Comment)comments[i];
            comment.Remove();
        }
    }
    // ExEnd
    private static Dictionary<int, String> GetCommentedText(Document doc)
    {
        Dictionary<Int32, String> commentedTexts = new Dictionary<Int32, String>();
        CommentedTextFinder finder = new CommentedTextFinder(commentedTexts);
        doc.Accept(finder);
        return commentedTexts;
    }
}

Note*: I was use DocumentVisitor as you recommended

Hello
Thanks for your request. I think in your case you should use DocumentVisitor to replace commented text. Please see the following code:

Document doc = new Document("C:\\Temp\\TestFile.docx");
// Get all comments from the document.
Node[] comments = doc.GetChildNodes(NodeType.Comment, true).ToArray();
foreach (Comment comment in comments)
{
    if (comment.ToTxt().Contains("willBeInSession"))
    {
        CommentedTextChanger changer = new CommentedTextChanger("NEW", comment.Id);
        doc.Accept(changer);
    }
}
doc.Save("C:\\Temp\\Out.docx");
private class CommentedTextChanger : DocumentVisitor
{
    public CommentedTextChanger(string replaceWith, int commentId)
    {
        mReplaceWith = replaceWith;
        mCommentId = commentId;
    }
    // /
    // / Called when a Run node is encountered in the document.
    // /
    public override VisitorAction VisitRun(Run run)
    {
        if (mReplace)
            run.Remove();
        // Let the visitor continue visiting other nodes.
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeStart(CommentRangeStart commentRangeStart)
    {
        if (commentRangeStart.Id == mCommentId)
            mReplace = true;
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeEnd(CommentRangeEnd commentRangeEnd)
    {
        if (commentRangeEnd.Id == mCommentId)
        {
            mReplace = false;
            DocumentBuilder builder = new DocumentBuilder((Document)commentRangeEnd.Document);
            builder.MoveTo(commentRangeEnd);
            builder.Write(mReplaceWith);
        }
        return VisitorAction.Continue;
    }
    private string mReplaceWith;
    private int mCommentId;
    private bool mReplace;
}

Best regards,

Thank you for your reply, it working but it the replace text change the format of document. Changed text is smaller than other. Is it because of trial version or I need to do more something? Do you have some sample to keep paragraph format for Changed Text?

Hello
Thanks for your inquiry. In this case you can try changing your code as shown below:

private class CommentedTextChanger : DocumentVisitor
{
    public CommentedTextChanger(string replaceWith, int commentId)
    {
        mReplaceWith = replaceWith;
        mCommentId = commentId;
    }
    // /
    // / Called when a Run node is encountered in the document.
    // /
    public override VisitorAction VisitRun(Run run)
    {
        if (mReplace)
            run.Text = string.Empty;
        // Let the visitor continue visiting other nodes.
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeStart(CommentRangeStart commentRangeStart)
    {
        if (commentRangeStart.Id == mCommentId)
            mReplace = true;
        return VisitorAction.Continue;
    }
    // /
    // / Called when visiting of a CommentRangeStart node is ended in the document.
    // /
    public override VisitorAction VisitCommentRangeEnd(CommentRangeEnd commentRangeEnd)
    {
        if (commentRangeEnd.Id == mCommentId)
        {
            mReplace = false;
            DocumentBuilder builder = new DocumentBuilder((Document)commentRangeEnd.Document);
            if (commentRangeEnd.PreviousSibling != null)
                builder.MoveTo(commentRangeEnd.PreviousSibling);
            else
                builder.MoveTo(commentRangeEnd);
            builder.Write(mReplaceWith);
        }
        return VisitorAction.Continue;
    }
    private string mReplaceWith;
    private int mCommentId;
    private bool mReplace;
}

Best regards,

Thank for your reply. It’s working. Now when I replace text of numeric bullet list by blank, the number of bullet list is still there. How I can remove empty numeric bullet list item with your CommentedTextCharger? Thank for your helps

Hi
Thanks for your request. I think in your case you should simply add VisitParagraphEnd method where check whether the paragraph is list item and is empty. If so, simply remove it.
Best regards,

A post was split to a new topic: Get comments of document