Retrieve comments from a word processing document

This topic describes how to use the classes in the Open XML SDK for Office to programmatically retrieve the comments from the main document part in a word processing document.


Open the Existing Document for Read-only Access

To open an existing document, instantiate the WordprocessingDocument class as shown in the following using statement. In the same statement, open the word processing file at the specified fileName by using the Open(String, Boolean, OpenSettings) method. To open the file for editing the Boolean parameter is set to true. In this example you just need to read the file; therefore, you can open the file for read-only access by setting the Boolean parameter to false.

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileName, false))
{
    if (wordDoc.MainDocumentPart is null || wordDoc.MainDocumentPart.WordprocessingCommentsPart is null)
    {
        throw new System.ArgumentNullException("MainDocumentPart and/or WordprocessingCommentsPart is null.");
    }

With v3.0.0+ the Close() method has been removed in favor of relying on the using statement. It ensures that the Dispose() method is automatically called when the closing brace is reached. The block that follows the using statement establishes a scope for the object that is created or named in the using statement. Because the WordprocessingDocument class in the Open XML SDK automatically saves and closes the object as part of its IDisposable implementation, and because Dispose() is automatically called when you exit the block, you do not have to explicitly call Save() or Dispose() as long as you use a using statement.


Comments Element

The comments and comment elements are crucial to working with comments in a word processing file. It is important in this code example to familiarize yourself with those elements.

The following information from the ISO/IEC 29500 specification introduces the comments element.

comments (Comments Collection)

This element specifies all of the comments defined in the current document. It is the root element of the comments part of a WordprocessingML document.

Consider the following WordprocessingML fragment for the content of a comments part in a WordprocessingML document:

    <w:comments>
      <w:comment … >
        …
      </w:comment>
    </w:comments>

© ISO/IEC 29500: 2016

The following XML schema segment defines the contents of the comments element.

    <complexType name="CT_Comments">
       <sequence>
           <element name="comment" type="CT_Comment" minOccurs="0" maxOccurs="unbounded"/>
       </sequence>
    </complexType>

Comment Element

The following information from the ISO/IEC 29500 specification introduces the comment element.

comment (Comment Content)

This element specifies the content of a single comment stored in the comments part of a WordprocessingML document.

If a comment is not referenced by document content via a matching id attribute on a valid use of the commentReference element, then it may be ignored when loading the document. If more than one comment shares the same value for the id attribute, then only one comment shall be loaded and the others may be ignored.

Consider a document with text with an annotated comment as follows:

Document text with annotated comment

This comment is represented by the following WordprocessingML fragment.

    <w:comment w:id="1" w:initials="User">
      …
    </w:comment>

The comment element specifies the presence of a single comment within the comments part.

© ISO/IEC 29500: 2016

The following XML schema segment defines the contents of the comment element.

    <complexType name="CT_Comment">
       <complexContent>
           <extension base="CT_TrackChange">
              <sequence>
                  <group ref="EG_BlockLevelElts" minOccurs="0" maxOccurs="unbounded"/>
              </sequence>
              <attribute name="initials" type="ST_String" use="optional"/>
           </extension>
       </complexContent>
    </complexType>

How the Sample Code Works

After you have opened the file for read-only access, you instantiate the WordprocessingCommentsPart class. You can then display the inner text of the Comment element.

WordprocessingCommentsPart commentsPart = wordDoc.MainDocumentPart.WordprocessingCommentsPart;

if (commentsPart is not null && commentsPart.Comments is not null)
{
    foreach (Comment comment in commentsPart.Comments.Elements<Comment>())
    {
        Console.WriteLine(comment.InnerText);
    }
}

Sample Code

The following is the complete sample code in both C# and Visual Basic.

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;

static void GetCommentsFromDocument(string fileName)
{
    using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(fileName, false))
    {
        if (wordDoc.MainDocumentPart is null || wordDoc.MainDocumentPart.WordprocessingCommentsPart is null)
        {
            throw new System.ArgumentNullException("MainDocumentPart and/or WordprocessingCommentsPart is null.");
        }

        WordprocessingCommentsPart commentsPart = wordDoc.MainDocumentPart.WordprocessingCommentsPart;

        if (commentsPart is not null && commentsPart.Comments is not null)
        {
            foreach (Comment comment in commentsPart.Comments.Elements<Comment>())
            {
                Console.WriteLine(comment.InnerText);
            }
        }
    }
}

See also