このトピックでは、Open XML SDK for Office のクラスを使用して、ワープロ ドキュメントのメイン ドキュメント パーツからコメントをプログラムで取得する方法について説明します。
既存のドキュメントを読み取り専用で開く
既存のドキュメントを開くには、次の using ステートメントに示すように、WordprocessingDocument クラスをインスタンス化します。 同じステートメントで、Open(String, Boolean, OpenSettings) メソッドを使用して、指定したfileNameでワープロ ファイルを開きます。 編集用のファイルを開くには、Boolean パラメーターを true に設定します。 この例では、ファイルを読み取るだけです。したがって、Boolean パラメーターを 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.");
}
v3.0.0 以降では、using ステートメントに依存することを優先して、Close() メソッドが削除されました。
これにより、閉じかっこに達したときに、 Dispose() メソッドが自動的に呼び出されます。 using ステートメントに続くブロックは、using ステートメントで作成または名前付けされたオブジェクトのスコープを確立します。 Open XML SDK の WordprocessingDocument クラスは、IDisposable実装の一部としてオブジェクトを自動的に保存および閉じます。また、ブロックを終了するとDispose()が自動的に呼び出されるため、using ステートメントを使用する限り、明示的にSave()またはDispose()を呼び出す必要はありません。
Comments 要素
ワープロ ファイルでコメントを操作するには、 comments 要素と comment 要素が不可欠です。 このコード例では、これらの要素に習熟することが重要です。
次の記述は ISO/IEC 29500 の仕様からの引用で、comments 要素について説明しています。
comments (Comments コレクション)
この要素は、現在のドキュメントに定義されているすべてのコメントを指定します。 これは、WordprocessingML ドキュメントのコメント パーツのルート要素です。
WordprocessingML ドキュメントのコメント パーツのコンテンツを表す次の WordprocessingML フラグメントを考えてみます。
<w:comments>
<w:comment … >
…
</w:comment>
</w:comments>
© ISO/IEC 29500: 2016
次の XML スキーマ セグメントは、comments 要素のコンテンツを定義します。
<complexType name="CT_Comments">
<sequence>
<element name="comment" type="CT_Comment" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
Comment 要素
次の記述は ISO/IEC 29500 の仕様からの引用で、comment 要素について説明しています。
comment (Comment コンテンツ)
この要素は、WordprocessingML ドキュメントのコメント パーツに格納される単一のコメントのコンテンツを指定します。
有効な方法で使用される commentReference 要素で一致する id 属性を通じて、ドキュメント コンテンツからコメントが参照されていない場合は、ドキュメントの読み込み時に、コメントは無視されることがあります。 複数のコメントで同じ値の id 属性を共有している場合は、コメントが 1 つだけ読み込まれ、その他のコメントは無視されることがあります。
注釈付きコメントを含むドキュメントは次のようになります。
このコメントを WordprocessingML フラグメントで表すと、次のようになります。
<w:comment w:id="1" w:initials="User">
…
</w:comment>
comment 要素は、コメント パーツ内に単一のコメントが存在することを指定します。
© ISO/IEC 29500: 2016
次の XML スキーマ セグメントは、comment 要素のコンテンツを定義します。
<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>
サンプル コードの動作のしくみ
読み取り専用アクセス用にファイルを開いた後、 WordprocessingCommentsPart クラスをインスタンス化します。 その後、 Comment 要素の内部テキストを表示できます。
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);
}
}
サンプル コード
以下に、C# と 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);
}
}
}
}