Open XML オブジェクト モデルを使用して Word 2007 ファイルを操作する (パート 2/3)

概要 : この記事は、Microsoft Office Word 2007 ファイルのアクセスと操作に使用できる Open XML オブジェクト モデルのコードについて説明している 3 つの記事で構成されるシリーズのパート 2 です。(8 印刷ページ)

Frank Rice、Microsoft Corporation

2007 年 8 月

適用対象 : Microsoft Office Word 2007

目次

  • 概要

  • ドキュメントから非表示テキストを削除する

  • ドキュメント アプリケーション プロパティを取得する

  • マクロ有効ドキュメントを DOCX ファイルに変換する

  • コア ドキュメント プロパティを取得する

  • カスタム ドキュメント プロパティを取得する

  • コア ドキュメント プロパティを設定する

  • まとめ

パート 1 の「Open XML オブジェクト モデルを使用して Word 2007 ファイルを操作する (パート 1/3)」を参照してください。

概要

2007 Microsoft Office system では、Office Open XML 形式と呼ばれる、XML に基づく新しいファイル形式が導入されています。Microsoft Office Word 2007、Microsoft Office Excel 2007、および Microsoft Office PowerPoint 2007 では、このファイル形式が既定のファイル形式として使用されます。Microsoft では, .NET Framework 3.0 テクノロジの一部として、System.IO.Packaging 名前空間でこれらのファイルにアクセスするためのライブラリを「Microsoft SDK for Open XML Formats テクノロジ プレビュー」に用意しています。Open XML オブジェクト モデルは System.IO.Packaging アプリケーション プログラミング インターフェイス (API) を基盤として作成されており、Open XML ドキュメントを操作するための厳密に型指定されたパーツ クラスを備えています。以下のセクションでは、Open XML オブジェクト モデルを使用して Word 2007 ファイルにアクセスおよび操作することができるコードについて説明します。

ドキュメントから非表示テキストを削除する

次のコードでは、Word 2007 ドキュメント内の非表示テキストを含むノードをメイン ドキュメント パーツから削除します。

Public Sub WDDeleteHiddenText(ByVal docName As String)
   ' Given a document name, delete all the hidden text.
   Const wordmlNamespace As String = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html"
   Dim wdDoc As WordprocessingDocument = WordprocessingDocument.Open(docName, true)
   Using (wdDoc)
      ' Manage namespaces to perform XPath queries.
      Dim nt As NameTable = New NameTable
      Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
      nsManager.AddNamespace("w", wordmlNamespace)
      ' Get the document part from the package.
      ' Load the XML in the part into an XmlDocument instance.
      Dim xdoc As XmlDocument = New XmlDocument(nt)
      xdoc.Load(wdDoc.MainDocumentPart.GetStream)
      Dim hiddenNodes As XmlNodeList = xdoc.SelectNodes("//w:vanish", nsManager)
      For Each hiddenNode As System.Xml.XmlNode In hiddenNodes
         Dim topNode As XmlNode = hiddenNode.ParentNode.ParentNode
         Dim topParentNode As XmlNode = topNode.ParentNode
         topParentNode.RemoveChild(topNode)
         If Not topParentNode.HasChildNodes Then
            topParentNode.ParentNode.RemoveChild(topParentNode)
         End If
      Next
      ' Save the document XML back to its part.
      xdoc.Save(wdDoc.MainDocumentPart.GetStream(FileMode.Create, FileAccess.Write))
   End Using
End Sub
public static void WDDeleteHiddenText(string docName)
{
   // Given a document name, delete all the hidden text.
   const string wordmlNamespace = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html";
   using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(docName, true))
   {
      // Manage namespaces to perform XPath queries.
      NameTable nt = new NameTable();
      XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
      nsManager.AddNamespace("w", wordmlNamespace);
      // Get the document part from the package.
      // Load the XML in the part into an XmlDocument instance.
      XmlDocument xdoc = new XmlDocument(nt);
      xdoc.Load(wdDoc.MainDocumentPart.GetStream());
      XmlNodeList hiddenNodes = xdoc.SelectNodes("//w:vanish", nsManager);
      foreach (System.Xml.XmlNode hiddenNode in hiddenNodes)
      {
         XmlNode topNode = hiddenNode.ParentNode.ParentNode;
         XmlNode topParentNode = topNode.ParentNode;
         topParentNode.RemoveChild(topNode);
         if (!(topParentNode.HasChildNodes))
         {
            topParentNode.ParentNode.RemoveChild(topParentNode);
         }
      }

      // Save the document XML back to its part.
      xdoc.Save(wdDoc.MainDocumentPart.GetStream(FileMode.Create, FileAccess.Write));
   }
}

このコード例では、最初に WDDeleteHiddenText メソッドが呼び出され、Word 2007 ドキュメントへの参照が渡されます。次に、Office Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトが入力ドキュメントに基づいて作成されます。次に、XPath クエリを設定するために名前空間マネージャを作成します。次に、メモリ常駐 XML ドキュメントを一時ホルダとして作成し、そのドキュメントにメイン ドキュメント パーツからマークアップおよびデータをロードします。その後のコードは、XPath 式 //w:vanish を使用して非表示テキスト ノードを検索し、ノードのリストをコンパイルします。次に、ノード リストをループ処理し、親ノードおよび子ノードを削除します。

For Each hiddenNode As System.Xml.XmlNode In hiddenNodes
   Dim topNode As XmlNode = hiddenNode.ParentNode.ParentNode
   Dim topParentNode As XmlNode = topNode.ParentNode
   topParentNode.RemoveChild(topNode)
   If Not topParentNode.HasChildNodes Then
      topParentNode.ParentNode.RemoveChild(topParentNode)
   End If
Next
foreach (System.Xml.XmlNode hiddenNode in hiddenNodes)
{
   XmlNode topNode = hiddenNode.ParentNode.ParentNode;
   XmlNode topParentNode = topNode.ParentNode;
   topParentNode.RemoveChild(topNode);
   if (!(topParentNode.HasChildNodes))
   {
      topParentNode.ParentNode.RemoveChild(topParentNode);
   }
}

最後に、更新された WordprocessingML マークアップが元のメイン ドキュメント パーツに保存されます。

ドキュメント アプリケーション プロパティを取得する

次のコードでは、ドキュメント内の拡張プロパティ パーツ (app.xml) に含まれたアプリケーション プロパティの値を取得します。

Public Shared Function WDRetrieveAppProperty(ByVal docName As String, ByVal propertyName As String) As String
   ' Given a document name and an app property, retrieve the value of the property.
   ' Note that because this code uses the SelectSingleNode method,
   ' the search is case sensitive. That is, looking for "Words" is not 
   ' the same as looking for "words".
   Const appPropertiesSchema As String = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html"
   Dim propertyValue As String = string.Empty
   Dim wdDoc As WordprocessingDocument = WordprocessingDocument.Open(docName, false)

   ' Manage namespaces to perform Xml XPath queries.
   Dim nt As NameTable = New NameTable
   Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
   nsManager.AddNamespace("d", appPropertiesSchema)

   ' Get the properties from the package.
   Dim xdoc As XmlDocument = New XmlDocument(nt)

   ' Load the XML in the part into an XmlDocument instance.
   xdoc.Load(wdDoc.ExtendedFilePropertiesPart.GetStream)
   Dim searchString As String = String.Format("//d:Properties/d:{0}", propertyName)
   Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
   If Not (xNode = Nothing) Then
      propertyValue = xNode.InnerText
   End If

   Return propertyValue
End Function
public static string WDRetrieveAppProperty(string docName, string propertyName)
{
   // Given a document name and an app property, retrieve the value of the property.
   // Note that because this code uses the SelectSingleNode method,
   // the search is case sensitive. That is, looking for "Words" is not 
   // the same as looking for "words".

   const string appPropertiesSchema = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html";

   string propertyValue = string.Empty;

   using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(docName, false))
   {
      // Manage namespaces to perform XML XPath queries.
      NameTable nt = new NameTable();
      XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
      nsManager.AddNamespace("d", appPropertiesSchema);

      // Get the properties from the package.
      XmlDocument xdoc = new XmlDocument(nt);

      // Load the XML in the part into an XmlDocument instance.
      xdoc.Load(wdDoc.ExtendedFilePropertiesPart.GetStream());

      string searchString = string.Format("//d:Properties/d:{0}", propertyName);
      XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
      if (!(xNode == null))
      {
         propertyValue = xNode.InnerText;
      }
   }
   return propertyValue;
}

このコード例は、最初に WDRetrieveAppProperty メソッドを呼び出し、Word 2007 ドキュメントへの参照および取得するアプリケーション プロパティの名前を渡します。次に、Office Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトを入力ドキュメントに基づいて作成します。次に、XPath クエリを設定するために名前空間マネージャを作成します。次に、メモリ常駐 XML ドキュメントを一時ホルダとして作成し、そのドキュメントに拡張プロパティ パーツ (app.xml) からマークアップおよびデータをロードします。検索文字列を XPath クエリとして設定し、d:Properties ノードを検索します。

Dim searchString As String = String.Format("//d:Properties/d:{0}", propertyName)
Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
If Not (xNode = Nothing) Then
   propertyValue = xNode.InnerText
End If
string searchString = string.Format("//d:Properties/d:{0}", propertyName);
XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
if (!(xNode == null))
{
   propertyValue = xNode.InnerText;
}

次に、指定したアプリケーション プロパティが格納されているノードを選択し、そのテキストを戻り変数に割り当てます。

マクロ有効ドキュメントを DOCX ファイルに変換する

次のコードは、すべての Microsoft Visual Basic for Applications (VBA) パーツをドキュメントから削除します。また、マクロが有効化されている .docm ファイルをマクロが無効化された .docx ファイルに変換します。

Public Sub WDConvertDOCMToDOCX(ByVal docName As String)
   ' Given a DOCM file (with macro storage), remove the VBA 
   ' project, reset the document type, and save the document with a new name.
   Dim vbaRelationshipType As String = "https://schemas.microsoft.com/office/2006/relationships/vbaProject"
   Dim wdDoc As WordprocessingDocument = WordprocessingDocument.Open(docName, True)
   Using (wdDoc)
      wdDoc.ChangeDocumentType(WordprocessingDocumentType.Document)
      Dim partsToDel As List(Of ExtendedPart) = New List(Of ExtendedPart)()
      For Each part As ExtendedPart In wdDoc.MainDocumentPart.GetPartsOfType(Of ExtendedPart)()
         If (part.RelationshipType = vbaRelationshipType) Then
            partsToDel.Add(part)
         End If
      Next part
      wdDoc.MainDocumentPart.DeleteParts(partsToDel)
   End Using

   ' Generate the new file name.
   Dim newFileName As String = (Path.GetDirectoryName(docName) + ("\" _
                    + (Path.GetFileNameWithoutExtension(docName) + ".docx")))
   ' If the new file exists, delete it. You may
   ' want to make this code less destructive.
   If File.Exists(newFileName) Then
      File.Delete(newFileName)
   End If
   File.Move(docName, newFileName)
End Sub
public static void WDConvertDOCMToDOCX(string docName)
{
   // Given a DOCM file (with macro storage), remove the VBA 
   // project, reset the document type, and save the document with a new name.

   const string vbaRelationshipType = "https://schemas.microsoft.com/office/2006/relationships/vbaProject";

   using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(docName, true))
   {
      wdDoc.ChangeDocumentType(WordprocessingDocumentType.Document);
      List<ExtendedPart> partsToDel = new List<ExtendedPart>();
      foreach (ExtendedPart part in wdDoc.MainDocumentPart.GetPartsOfType<ExtendedPart>())
      {
         if (part.RelationshipType == vbaRelationshipType) partsToDel.Add(part);
      }
      wdDoc.MainDocumentPart.DeleteParts(partsToDel);
   }

   // Generate the new file name.
   string newFileName = Path.GetDirectoryName(docName) + @"\" + Path.GetFileNameWithoutExtension(docName) + ".docx";
   // If the new file exists, delete it. You may
   // want to make this code less destructive.
   if (File.Exists(newFileName))
   {
      File.Delete(newFileName);
   }
   File.Move(docName, newFileName);
}

最初に、WDConvertDOCMToDOCX メソッドを呼び出し、Word 2007 ドキュメントへの参照を渡します。次に、Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトを入力ドキュメントに基づいて作成します。WordprocessingDocument オブジェクトの ChangeDocumentType メソッドを呼び出し、ドキュメントのタイプをマクロ有効ファイルから、マクロが無効の既定のドキュメント形式に変更します。

wdDoc.ChangeDocumentType(WordprocessingDocumentType.Document)
wdDoc.ChangeDocumentType(WordprocessingDocumentType.Document);

パッケージ内の拡張パーツをループ処理し、VBA 参照を持つパーツが存在するかどうかをテストします。VBA 参照を含むすべてのパーツを、削除するパーツのリストに追加します。

For Each part As ExtendedPart In wdDoc.MainDocumentPart.GetPartsOfType(Of ExtendedPart)()
   If (part.RelationshipType = vbaRelationshipType) Then
      partsToDel.Add(part)
   End If
Next part
wdDoc.MainDocumentPart.DeleteParts(partsToDel)
foreach (ExtendedPart part in wdDoc.MainDocumentPart.GetPartsOfType<ExtendedPart>())
{
   if (part.RelationshipType == vbaRelationshipType) partsToDel.Add(part);
}
wdDoc.MainDocumentPart.DeleteParts(partsToDel);

このパーツを削除するには、メイン ドキュメント パーツの DeleteParts メソッドを呼び出します。最後に、更新されたドキュメント タイプを反映して元のドキュメントの名前が変更されます。

コア ドキュメント プロパティを取得する

次のコードでは、ドキュメント内のコア プロパティ パーツ (core.xml) に含まれたコア プロパティの値を取得します。

Public Function WDRetrieveCoreProperty(ByVal docName As String, ByVal propertyName As String) As String
   ' Given a document name and a core property, retrieve the value of the property.
   ' Note that because this code uses the SelectSingleNode method, 
   ' the search is case sensitive. That is, looking for "Author" is not 
   ' the same as looking for "author".

   Const corePropertiesSchema As String = "https://msdn.microsoft.com/ja-jp/library/bb447589.aspx"
   Const dcPropertiesSchema As String = "http://purl.org/dc/elements/1.1/"
   Const dcTermsPropertiesSchema As String = "http://purl.org/dc/terms/"
   Dim propertyValue As String = String.Empty
   Dim wdPackage As WordprocessingDocument = WordprocessingDocument.Open(docName, True)

   ' Get the core properties part (core.xml).
   Dim corePropertiesPart As CoreFilePropertiesPart = wdPackage.CoreFilePropertiesPart

   ' Manage namespaces to perform XML XPath queries.
   Dim nt As NameTable = New NameTable
   Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
   nsManager.AddNamespace("cp", corePropertiesSchema)
   nsManager.AddNamespace("dc", dcPropertiesSchema)
   nsManager.AddNamespace("dcterms", dcTermsPropertiesSchema)

   ' Get the properties from the package.
   Dim xdoc As XmlDocument = New XmlDocument(nt)
   ' Load the XML in the part into an XmlDocument instance.
   xdoc.Load(corePropertiesPart.GetStream)

   Dim searchString As String = String.Format("//cp:coreProperties/{0}", propertyName)
   Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
   If Not (xNode Is Nothing) Then
      propertyValue = xNode.InnerText
   End If
   Return propertyValue
End Function
public static string WDRetrieveCoreProperty(string docName, string propertyName)
{
   // Given a document name and a core property, retrieve the value of the property.
   // Note that because this code uses the SelectSingleNode method, 
   // the search is case sensitive. That is, looking for "Author" is not 
   // the same as looking for "author".

   const string corePropertiesSchema = "https://msdn.microsoft.com/ja-jp/library/bb447589.aspx";
   const string dcPropertiesSchema = "http://purl.org/dc/elements/1.1/";
   const string dcTermsPropertiesSchema = "http://purl.org/dc/terms/";

   string propertyValue = string.Empty;

   using (WordprocessingDocument wdPackage = WordprocessingDocument.Open(docName, true))
   {
      // Get the core properties part (core.xml).
      CoreFilePropertiesPart corePropertiesPart = wdPackage.CoreFilePropertiesPart;

      // Manage namespaces to perform XML XPath queries.
      NameTable nt = new NameTable();
      XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
      nsManager.AddNamespace("cp", corePropertiesSchema);
      nsManager.AddNamespace("dc", dcPropertiesSchema);
      nsManager.AddNamespace("dcterms", dcTermsPropertiesSchema);

      // Get the properties from the package.
      XmlDocument xdoc = new XmlDocument(nt);

      // Load the XML in the part into an XmlDocument instance.
      xdoc.Load(corePropertiesPart.GetStream());

      string searchString = string.Format("//cp:coreProperties/{0}", propertyName);

      XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
      if (!(xNode == null))
      {
         propertyValue = xNode.InnerText;
      }
   }

   return propertyValue;
}

このコード例は、最初に WDRetrieveCoreProperty メソッドを呼び出し、Word 2007 ドキュメントへの参照および取得するアプリケーション プロパティの名前を渡します。次に、Office Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトを入力ドキュメントに基づいて作成します。CoreFilePropertiesPart パーツを取得します。次に、XPath クエリを設定するために名前空間マネージャを作成します。メモリ常駐 XML ドキュメントを一時ホルダとして作成し、そのドキュメントにコア ファイル プロパティ パーツ (core.xml) からマークアップおよびデータをロードします。次に、検索文字列を XPath クエリとして設定します。検索文字列を XPath クエリとして設定し、cp:coreProperties ノードを検索します。

Dim searchString As String = String.Format("//cp:coreProperties/{0}", propertyName)
Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
If Not (xNode Is Nothing) Then
   propertyValue = xNode.InnerText
End If
string searchString = string.Format("//cp:coreProperties/{0}", propertyName);

XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
if (!(xNode == null))
{
   propertyValue = xNode.InnerText;
}

次に、指定したプロパティが格納されているノードを選択し、そのテキストを戻り変数に割り当てます。

カスタム ドキュメント プロパティを取得する

次のコードでは、ドキュメント内のカスタム プロパティ パーツ (custom.xml) に含まれたカスタム プロパティの値を取得します。

Public Function WDRetrieveCustomProperty(ByVal docName As String, ByVal propertyName As String) As String
   ' Given a document name and a core property, retrieve the value of the property.
   ' Note that because this code uses the SelectSingleNode method
   ' the search is case sensitive. That is, looking for "Author" is not 
   ' the same as looking for "author".

   Const customPropertiesSchema As String = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html"
   Const customVTypesSchema As String = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html"
   Dim propertyValue As String = String.Empty
   Dim wdPackage As WordprocessingDocument = WordprocessingDocument.Open(docName, True)

   ' Get the custom properties part (custom.xml).
   Dim customPropertiesPart As CustomFilePropertiesPart = wdPackage.CustomFilePropertiesPart
   ' There may not be a custom properties part.
   If (Not (customPropertiesPart) Is Nothing) Then
      ' Manage namespaces to perform Xml XPath queries.
      Dim nt As NameTable = New NameTable
      Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
      nsManager.AddNamespace("d", customPropertiesSchema)
      nsManager.AddNamespace("vt", customVTypesSchema)

      ' Get the properties from the package.
      Dim xdoc As XmlDocument = New XmlDocument(nt)

      ' Load the XML in the part into an XmlDocument instance.
      xdoc.Load(customPropertiesPart.GetStream)
      Dim searchString As String = String.Format("d:Properties/d:property[@name='{0}']", propertyName)
      Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
      If (Not (xNode) Is Nothing) Then
         propertyValue = xNode.InnerText
      End If
    End If
   Return propertyValue
End Function
public static string WDRetrieveCustomProperty(string docName, string propertyName)
{
   const string customPropertiesSchema = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html";
   const string customVTypesSchema = "http://schemas.liquid-technologies.com/OfficeOpenXML/2006/default.html";

   string propertyValue = string.Empty;

   using (WordprocessingDocument wdPackage = WordprocessingDocument.Open(docName, true))
   {
      // Get the custom properties part (custom.xml).
      CustomFilePropertiesPart customPropertiesPart = wdPackage.CustomFilePropertiesPart;

      // There may not be a custom properties part.
      if (customPropertiesPart != null)
      {
         // Manage namespaces to perform XML XPath queries.
         NameTable nt = new NameTable();
         XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
         nsManager.AddNamespace("d", customPropertiesSchema);
         nsManager.AddNamespace("vt", customVTypesSchema);

         // Get the properties from the package.
         XmlDocument xdoc = new XmlDocument(nt);

         // Load the XML in the part into an XmlDocument instance.
         xdoc.Load(customPropertiesPart.GetStream());

         string searchString = string.Format("d:Properties/d:property[@name='{0}']", propertyName);
         XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
         if ((xNode != null))
         {
            propertyValue = xNode.InnerText;
         }
      }
   }
   return propertyValue;
}

このコード例は、最初に WDRetrieveCustomProperty メソッドを呼び出し、Word 2007 ドキュメントへの参照および取得するアプリケーション プロパティの名前を渡します。次に、Office Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトを入力ドキュメントに基づいて作成します。CustomFilePropertiesPart パーツを取得し、変数に割り当てます。パッケージにカスタム プロパティ パーツが含まれている場合があるため、変数をテストして空であるかどうかを確認する必要があります。

カスタム プロパティ パーツが存在する場合は、XPath クエリを設定するために名前空間マネージャを作成します。メモリ常駐 XML ドキュメントを一時ホルダとして作成し、そのドキュメントにカスタム ファイル プロパティ パーツ (custom.xml) からマークアップおよびデータをロードします。次に、検索文字列を XPath クエリとして設定します。検索文字列を XPath クエリとして設定し、指定したプロパティを含む d:Properties/d:property ノードを検索します。

xdoc.Load(customPropertiesPart.GetStream)
Dim searchString As String = String.Format("d:Properties/d:property[@name='{0}']", propertyName)
Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
If (Not (xNode) Is Nothing) Then
   propertyValue = xNode.InnerText
End If
string searchString = string.Format("d:Properties/d:property[@name='{0}']", propertyName);
XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
if ((xNode != null))
{
   propertyValue = xNode.InnerText;
}

次に、指定したプロパティが格納されているノードを選択し、そのテキストを戻り変数に割り当てます。

コア ドキュメント プロパティを設定する

次のコードでは、ドキュメント内のコア プロパティの値を設定します。プロパティに新しい値が適切に設定されると、呼び出し元プロシージャに元の値が返され、失敗すると null 文字列が返されます。

Public Function WDSetCoreProperty(ByVal docName As String, ByVal propertyName As String, ByVal propertyValue As String) As String
   ' Given a document name, a property name, and a value, update the document.
   ' Note that you cannot set the value of a property that does not
   ' exist within the core.xml part. If you successfully updated the property
   ' value, return its old value.
   ' Attempting to modify a non-existent property raises an exception.

   ' Property names are case-sensitive.

   Const corePropertiesSchema As String = "https://msdn.microsoft.com/ja-jp/library/bb447589.aspx"
   Const dcPropertiesSchema As String = "http://purl.org/dc/elements/1.1/"
   Dim retVal As String = Nothing
   Dim wdPackage As WordprocessingDocument = WordprocessingDocument.Open(docName, True)
   Dim corePropertiesPart As CoreFilePropertiesPart = wdPackage.CoreFilePropertiesPart

   ' Manage namespaces to perform Xml XPath queries.
   Dim nt As NameTable = New NameTable
   Dim nsManager As XmlNamespaceManager = New XmlNamespaceManager(nt)
   nsManager.AddNamespace("cp", corePropertiesSchema)
   nsManager.AddNamespace("dc", dcPropertiesSchema)

   ' Get the properties from the package.
   Dim xdoc As XmlDocument = New XmlDocument(nt)

   ' Load the XML in the part into an XmlDocument instance:
   xdoc.Load(corePropertiesPart.GetStream)
   Dim searchString As String = String.Format("//cp:coreProperties/{0}", propertyName)
   Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
   If (xNode Is Nothing) Then
      ' Trying to set the value of a property that 
      ' does not exist? Throw an exception.
      Throw New ArgumentException("Invalid property name.")
   Else
      ' Get the current value.
      retVal = xNode.InnerText
      ' Now update the value.
      xNode.InnerText = propertyValue
      ' Save the properties XML back to its part.
      xdoc.Save(corePropertiesPart.GetStream)
   End If
   Return retVal
End Function
public static string WDSetCoreProperty(string docName, string propertyName, string propertyValue)
{
   // Given a document name, a property name, and a value, update the document.
   // Note that you cannot set the value of a property that does not
   //  exist within the core.xml part. If you successfully updated the property
   // value, return its old value.

   const string corePropertiesSchema = "https://msdn.microsoft.com/ja-jp/library/bb447589.aspx";
   const string dcPropertiesSchema = "http://purl.org/dc/elements/1.1/";

   string retVal = null;

   using (WordprocessingDocument wdPackage = WordprocessingDocument.Open(docName, true))
   {
      CoreFilePropertiesPart corePropertiesPart = wdPackage.CoreFilePropertiesPart; ;

      // Manage namespaces to perform Xml XPath queries.
      NameTable nt = new NameTable();
      XmlNamespaceManager nsManager = new XmlNamespaceManager(nt);
      nsManager.AddNamespace("cp", corePropertiesSchema);
      nsManager.AddNamespace("dc", dcPropertiesSchema);

      // Get the properties from the package.
      XmlDocument xdoc = new XmlDocument(nt);

      // Load the XML in the part into an XmlDocument instance:
      xdoc.Load(corePropertiesPart.GetStream());

      string searchString = string.Format("//cp:coreProperties/{0}", propertyName);
      XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
      if (xNode == null)
      {
         // Trying to set the value of a property that 
         // does not exist? Throw an exception.
         throw new ArgumentException("Invalid property name.");
      }
      else
      {
         // Get the current value.
         retVal = xNode.InnerText;

         // Now update the value.
         xNode.InnerText = propertyValue;

         // Save the properties XML back to its part.
         xdoc.Save(corePropertiesPart.GetStream());
       }
   }
   return retVal;
}

このコード例は、最初に WDSetCoreProperty メソッドを呼び出し、Word 2007 ドキュメントへの参照、コア プロパティの名前、およびプロパティに設定する新しい値を渡します。次に、Office Open XML ファイル形式パッケージを表す WordprocessingDocument オブジェクトを入力ドキュメントに基づいて作成します。CoreFilePropertiesPart パーツを取得します。このコード例では、XPath クエリを設定するために名前空間マネージャを作成します。メモリ常駐 XML ドキュメントを一時ホルダとして作成し、そのドキュメントにコア ファイル プロパティ パーツ (core.xml) からマークアップおよびデータをロードします。次に、検索文字列を XPath クエリとして設定します。検索文字列を XPath クエリとして設定し、cp:coreProperties ノードを検索します。このパーツにプロパティが含まれている場合があるため、変数をテストして空であるかどうかを確認する必要があります。

Dim searchString As String = String.Format("//cp:coreProperties/{0}", propertyName)
Dim xNode As XmlNode = xdoc.SelectSingleNode(searchString, nsManager)
If (xNode Is Nothing) Then
   ' Trying to set the value of a property that 
   ' does not exist? Throw an exception.
   Throw New ArgumentException("Invalid property name.")
Else
   ' Get the current value.
   retVal = xNode.InnerText
   ' Now update the value.
   xNode.InnerText = propertyValue
   ' Save the properties XML back to its part.
   xdoc.Save(corePropertiesPart.GetStream)
End If
Return retVal
string searchString = string.Format("//cp:coreProperties/{0}", propertyName);
XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager);
if (xNode == null)
{
   // Trying to set the value of a property that 
   // does not exist? Throw an exception.
   throw new ArgumentException("Invalid property name.");
}
else
{
   // Get the current value.
   retVal = xNode.InnerText;

   // Now update the value.
   xNode.InnerText = propertyValue;

   // Save the properties XML back to its part.
   xdoc.Save(corePropertiesPart.GetStream());
}
return retVal;

プロパティが存在しない場合、このコードは例外をスローします。プロパティが存在する場合は、プロパティの現在の値が取得され、プロパティを含んでいるノードに新しい値が設定されます。最後に、更新されたマークアップがパッケージに保存され、呼び出し元プロシージャに元の値が返されます。

まとめ

この記事で説明したように、「Microsoft SDK for Open XML Formats テクノロジ プレビュー」を参照することで、Word 2007 ファイルの操作が非常に簡単になります。このシリーズのパート 3 の記事では、Open XML Formats SDK で実行できる他の一般的なタスクについて説明します。

追加情報

詳細については、以下のリソースを参照してください。

準備中 :