OpenXML获取DocParts的innertext会返回“错误!未知文档属性名称”

时间:2013-08-12 09:30:13

标签: c# ms-word openxml

我正在尝试使用openxml sdk 2.5获取word文档模板的内部结构。

关键是,当我调用docpart的innertext属性时,我添加了docproperty,它总是添加一个aditional“Error!Unknown document property name”。串...

  /// <summary>
  /// Examines a word document to create the data structure of autotexts
  /// </summary>
  /// <param name="document">Word document to be processed</param>
  /// <returns>OpenXMLAutoTextContainer</returns>
  public static OpenXMLAutotextContainer GetAutotextContainer(WordprocessingDocument document)
  {
     OpenXMLAutotextContainer result = null;

     try
     {
        result = new OpenXMLAutotextContainer()
        {
           Name = document.ExtendedFilePropertiesPart.Properties.Template.InnerText
        };

        result.OpenXMLAutoTextList = new Dictionary<string, OpenXMLAutotext>();

        List<CIProField> CIProFields = null;

        foreach (DocPart _docPart in document.MainDocumentPart.GlossaryDocumentPart.GlossaryDocument.DocParts)
        {
           if (_docPart.DocPartProperties.Category.Gallery.Val == "autoTxt")
           {
              CIProFields = new List<CIProField>();

              result.OpenXMLAutoTextList.Add(
                 _docPart.DocPartProperties.DocPartName.Val,
                 new OpenXMLAutotext()
                 {
                    Name = _docPart.DocPartProperties.DocPartName.Val,
                    Content = _docPart.DocPartBody.InnerText,
                    CIProFields = CIProFields
                 });
           }
        }
     }
     catch (Exception ex)
     {
        OpenXMLCustomException e = new OpenXMLCustomException(ex, "GetAutotextContainer");
        throw e;
     }

     return result;
  }
}

OpenXML SDK输出:

<w:docPart xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
   <w:docPartPr>
   <w:name w:val="W_DocProp01" />
   <w:style w:val="Normal" />
   <w:category>
     <w:name w:val="General" />
     <w:gallery w:val="autoTxt" />
   </w:category>
   <w:behaviors>
     <w:behavior w:val="content" />
   </w:behaviors>
   <w:guid w:val="{12809B83-5021-4211-A70D-EA3447274A83}" />
</w:docPartPr>
<w:docPartBody>
  <w:p w:rsidRPr="001E1D2D" w:rsidR="00F6185D" w:rsidP="001E1D2D" w:rsidRDefault="00F6185D">
    <w:pPr>
      <w:rPr>
        <w:lang w:val="es-ES" />
      </w:rPr>
    </w:pPr>
    <w:r>
      <w:rPr>
        <w:lang w:val="es-ES" />
      </w:rPr>
      <w:fldChar w:fldCharType="begin" />
    </w:r>
    <w:r>
      <w:rPr>
        <w:lang w:val="es-ES" />
      </w:rPr>
      <w:instrText>DOCPROPERTY "Test_W_DocProp01"</w:instrText>
    </w:r>
    <w:r>
      <w:rPr>
        <w:lang w:val="es-ES" />
      </w:rPr>
      <w:fldChar w:fldCharType="separate" />
    </w:r>
    <w:r>
      <w:rPr>
        <w:b />
        <w:bCs />
        <w:lang w:val="en-US" />
      </w:rPr>
      <w:t>Error! Unknown document property name.</w:t>
    </w:r>
    <w:r>
      <w:rPr>
        <w:lang w:val="es-ES" />
      </w:rPr>
      <w:fldChar w:fldCharType="end" />
    </w:r>
    </w:p>
    <w:p w:rsidR="00000000" w:rsidRDefault="00F6185D" />
  </w:docPartBody>
</w:docPart>

Quickwatch visual studio...

Word template view

1 个答案:

答案 0 :(得分:2)

您好像在引用文档中不存在的文档属性。您可以通过Word手动设置属性(2007年见http://office.microsoft.com/en-001/word-help/view-or-change-the-properties-for-an-office-document-HA010047524.aspx#BM15)或通过openXML(http://msdn.microsoft.com/en-us/library/ff936167(v=office.14).aspx

<强>更新

OpenXML不刷新属性。如果您插入了一个属性并且没有要求Word刷新它,您将收到您正在看到的消息 - 即使该属性已经存在。看一下这个更“官方”的答案 - http://social.msdn.microsoft.com/Forums/office/en-US/f72c9489-dc50-457b-8629-567f83882770/update-word-document-properties

我认为如果你打算使用OpenXML,你最好的选择就是像你一样阅读这些属性。获得名称后,不要查看存储在那里的值,而是获取相应的文档属性值。这样您就可以获得最新版本。您现在使用的工作方式是使用单词更新的最后一个值。

您可以使用以下方法获取自定义文档属性名称和值的字典 -

private static Dictionary<string, string> GetCustomDocumentProperties(WordprocessingDocument p_document)
    {            
        if (p_document.CustomFilePropertiesPart == null)
        {
            return new Dictionary<string, string>();
        }
        else
        {
            return p_document.CustomFilePropertiesPart.Properties.ToDictionary(p => ((CustomDocumentProperty) p).Name.InnerText,
                                                                          p => ((CustomDocumentProperty) p).InnerText);
        }
    }