Word 2013 Comments in WordOpenXML

Now that we’ve looked at Comments in the Word 2013 user interface and object model, it’s time to consider how this has been implemented in WordOpenXML and the Open XML SDK.

With Comments we have a situation where existing functionality is being extended. This means the incorporation of new namespaces in the WordOpenXML. In the case of Comments, we’re dealing with two of them:

  • w15=http://schemas.microsoft.com/office/word/2012/wordml
  • w14=http://schemas.microsoft.com/office/word/2010/wordml

In addition, new Parts have been implemented as “sub-folders” to the “word folder” in order to support the new functionality:

  • commentsExtended.xml
  • people.xml

Structure of the word "folder" in a Word 2013 "package"

The 2013 WordOpenXML of a Comment in comments.xml looks something like this:

<w:comment w:initials="TC" 
 w:date="2012-09-22T09:41:00Z" 
 w:author="Test Comments" w:id="0">
  <w:p w:rsidRDefault="00281480" w:rsidR="00281480" 
   w14:textId="571AB730" w14:paraId="4D593CE4">
    <w:pPr><w:pStyle w:val="CommentText"/></w:pPr>
       <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
            <w:annotationRef/></w:r>
       <w:r>
          <w:t>WordMeister needs to be added to the Custom Dictionary.</w:t>
       </w:r>
  </w:p>
</w:comment>

The <w:comment> element is as it was in earlier versions, the new functionality has been added as attributes to the <w:p> element: w14:textID and w14:paraId. For Comments, we’re only interested in w14:paraId. The paraId links the Comment to extended information in the part commentsExtended.xml.

Here’s how commentsExtended.xml looks, with the namespace declarations removed for clarity:

<w15:commentsEx>
  <w15:commentEx w15:done="0" w15:paraId="4D593CE4"/>
  <w15:commentEx w15:done="0" w15:paraId="03906312"/>
  <w15:commentEx w15:done="0" w15:paraId="0D8C2C03"/>
  <w15:commentEx w15:done="0" w15:paraId="4606D5DA"/>
  <w15:commentEx w15:done="0" w15:paraId="60FD53B4" w15:paraIdParent="4606D5DA"/>
  <w15:commentEx w15:done="0" w15:paraId="6FCECE2F"/>
  <w15:commentEx w15:done="0" w15:paraId="5286D8C5" w15:paraIdParent="6FCECE2F"/>
  <w15:commentEx w15:done="0" w15:paraId="00F632AA" w15:paraIdParent="6FCECE2F"/>
  <w15:commentEx w15:done="0" w15:paraId="3AC47D37" w15:paraIdParent="6FCECE2F"/>
</w15:commentsEx>

It’s apparent that this Part is storing three pieces of information concerning Word 2013 comments:

  • w15:done – whether the comment is finished; equivalent to Done in the object model
  • w15:paraId – matches to the paraId in comments.xml
  • w15:paraIdParent – also matches to the paraId in comments.xml

You might ask the purpose of w15:paraIdParent. This tells you that the Comment has been written as a “Reply” in a discussion. w15:paraIdParent tells you the top-level Comment in the discussion – the Ancestor in the object model.

The following diagram will give you an idea how the different parts fit together.

Diagram of how the different components of a Word 2013 "package" fit together for comments

Now, you might think that there’d be one entry in commentsExtended.xml for every paraId in comments.xml. This, however, is not necessarily the case, which means you have to be careful working back and forth between the two. If the user presses ENTER when typing a Comment, the Comment will contain multiple paragraphs. Each of these will have a different value stored in paraId:

<w:comment w:initials="TC" w:date="2012-09-22T10:17:00Z" 
 w:author="Cindy Meister" w:id="6">
  <w:p w:rsidRDefault="00281480" w:rsidR="00281480" 
   w14:textId="5F920C7E" w14:paraId="3CEC1C00">
    <w:pPr><w:pStyle w:val="CommentText"/></w:pPr>
      <w:r><w:rPr><w:rStyle w:val="CommentReference"/></w:rPr>
        <w:annotationRef/></w:r>
      <w:r>
        <w:t>This should be a second comment, but the user name is wrong?</w:t>
      </w:r></w:p>
  <w:p w:rsidRDefault="00281480" w:rsidR="00281480" 
   w14:textId="77777777" w14:paraId="5286D8C5">
    <w:pPr></w:pPr></w:p>
</w:comment>

If you compare the two paraId values with the xml from commentsExtended.xml you’ll see that the first paraId is missing. The link between the two parts goes over the last paragraph in the Comment, not the first.

Why this way was chosen, rather than linking via the Comment’s id attribute is a mystery. It certainly makes working with the OpenXML much more complex than it needed to be…

The Contact functionality, tracking user identities, is managed in people.xml. The link in this case is via the author attribute and presents no significant challenges:

<w:15:people>
  <w15:person w15:author="Test Comments">
    <w15:presenceInfo w15:providerId="None" w15:userId="Test Comments"/>
  </w15:person>
  <w15:person w15:author="Cindy Meister">
    <w15:presenceInfo w15:providerId="None" w15:userId="Cindy Meister"/>
  </w15:person>
</w15:people>

This may seem like a lot of background information, but it’s important to understand how these things link together before attempting to manipulate the Open XML. My next post will discuss how to work with the new functionality using the Open XML SDK.



Leave a Reply