Open XML 개체 모델을 사용한  Word 2007 파일 조작 (파트 2/3)

Open XML 개체 모델을 사용한  Word 2007 파일 조작 (파트 2/3)

개요 : 이 문서는 Microsoft Office Word 2007 파일의 액세스와 조작에 사용할 수 있는 Open XML 개체 모델의 코드를 설명하는 3부작 문서로 구성된 시리즈의 두번째 입니다.

Frank Rice, Microsoft Corporation

2007 년 8 월

적용 대상 : Microsoft Office Word 2007

목차

  • 개요

  • 문서에서 숨겨진 텍스트 삭제

  • 문서 응용 프로그램 속성 검색

  • 매크로 유효 문서를 DOCX 파일 변환

  • 핵심 문서 속성 검색

  • 사용자 지정 문서 속성 검색

  • 핵심 문서 속성 설정

  • 요약

개요

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 = "https://schemas.openxmlformats.org/wordprocessingml/2006/main"
   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 = "https://schemas.openxmlformats.org/wordprocessingml/2006/main";
   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 = "https://schemas.openxmlformats.org/officeDocument/2006/extended-properties"
   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 = "https://schemas.openxmlformats.org/officeDocument/2006/extended-properties";

   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) 파트를 문서에서 삭제합니다. 또, 매크로가 무효화된 .docx 파일을 매크로가 유효화된 .docm 파일 변환합니다.

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://schemas.openxmlformats.org/package/2006/metadata/core-properties"
   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://schemas.openxmlformats.org/package/2006/metadata/core-properties";
   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 = "https://schemas.openxmlformats.org/officeDocument/2006/custom-properties"
   Const customVTypesSchema As String = "https://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"
   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 = "https://schemas.openxmlformats.org/officeDocument/2006/custom-properties";
   const string customVTypesSchema = "https://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes";

   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://schemas.openxmlformats.org/package/2006/metadata/core-properties"
   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://schemas.openxmlformats.org/package/2006/metadata/core-properties";
   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에서 실행할 수 있는 다른 일반적인 작업을 설명합니다.