2011-03-11 18 views
3

環境:asp.net C#OPENXMLYASR - 另一種搜索和替換問題

好了,我一直在讀一噸的片段,並試圖重新發明輪子,但我希望有人爲幫助我更快地達到我的要求。我有多個文檔需要合併在一起...檢查...我可以使用openxml sdk來完成此操作。鳥在唱歌,太陽在閃閃發光。現在,我按照自己的方式使用該文檔,但我需要搜索並替換文本和/或內容控件。

我試過使用我自己的文本{替換這個},但是當我看着xml(將docx重命名爲zip並查看文件)時,{無處附近的文本。因此,我需要知道如何保護投票內容,以免他們分歧,或者我需要找到另一種搜索和替換方式。

我能夠搜索/替換,如果它是一個XML文件,但然後我回來不能輕鬆地結合doucments。

下面的代碼...正如我所說的...文件合併工作正常...只需要更換的東西。

*更新*改變了我的替換調用去標籤而不是正則表達式。我現在有了正確的信息,但.Replace電話似乎並不想工作。最後四行用於驗證我看到正確的標籤內容。我只是想現在替換這些內容。

protected void exeProcessTheDoc(object sender, EventArgs e) 
    { 
     string doc1 = Server.MapPath("~/Templates/doc1.docx"); 
     string doc2 = Server.MapPath("~/Templates/doc2.docx"); 
     string final_doc = Server.MapPath("~/Templates/extFinal.docx"); 

     File.Delete(final_doc); 
     File.Copy(doc1, final_doc); 

     using (WordprocessingDocument myDoc = WordprocessingDocument.Open(final_doc, true)) 
     { 
      string altChunkId = "AltChunkId2"; 

      MainDocumentPart mainPart = myDoc.MainDocumentPart; 
      AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
      AlternativeFormatImportPartType.WordprocessingML, altChunkId); 
      using (FileStream fileStream = File.Open(doc2, FileMode.Open)) 
      chunk.FeedData(fileStream); 
      AltChunk altChunk = new AltChunk(); 
      altChunk.Id = altChunkId; 
      mainPart.Document.Body.InsertAfter(altChunk, mainPart.Document.Body.Elements<Paragraph>().Last()); 
      mainPart.Document.Save(); 
     } 
     exeSearchReplace(final_doc); 
    } 

    public static void GetPropertyFromDocument(string document, string outdoc) 
    { 
     XmlDocument xmlProperties = new XmlDocument(); 

     using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, false)) 
     { 
      ExtendedFilePropertiesPart appPart = wordDoc.ExtendedFilePropertiesPart; 

      xmlProperties.Load(appPart.GetStream()); 
     } 
     XmlNodeList chars = xmlProperties.GetElementsByTagName("Company"); 
     chars.Item(0).InnerText.Replace("{ClientName}", "Penn Inc."); 

     StreamWriter sw; 
     sw = File.CreateText(outdoc); 
     sw.WriteLine(chars.Item(0).InnerText); 
     sw.Close(); 
    }  
} 

}

回答

1

如果我讀這個權利,你有類似「{代替我}」中的.docx,然後當你通過XML循環,你發現喜歡的東西<t>{replace</t><t> me</><t>}</t>或一些這樣的破壞。現在,用這樣的XML,創建一個替代「{替換我}」的例程是不可能的。

如果是這樣的話,那很可能與它被認爲是一個校樣錯誤有關。即就Word而言拼寫錯誤。原因是您已經在Word中打開文檔並打開了打樣。因此,文本被標記爲「isDirty」並分成不同的運行。

有關解決這種情況的兩種方法是:

  1. 客戶端。在Word中,只要確保所有校對錯誤已被更正或忽略。
  2. 格式端。使用MarkupSimplifier工具是Visual Studio 2010的Open XML Package Editor Power Tool的一部分,以在客戶端之外修復此問題。埃裏克·懷特有一個偉大的(並且及時爲您 - 短短數天之久)在這裏寫起來就可以了:Getting Started with Open XML PowerTools Markup Simplifier
+0

在正確的軌道。證明者是其中的一部分。標記簡化程序沒有幫助我,但能夠找到/解決分離問題。我似乎仍然無法找到該領域並取而代之。我的搜索和替換代碼的任何想法? – petronius31 2011-03-14 15:15:16

+0

這很難說。我不確定我會爲此嘗試使用StreamReader。爲什麼不把它作爲XML來獲取所有的'.Value'來搜索你的正則表達式文本,然後在最後按照你所做的和''保存'它。這裏有一個PowerPoint和VB.NET的例子:http://stackoverflow.com/questions/3903142/is-it-possible-to-update-a-powerpoint-slide-with-new-data-in-c/4504970# 4504970使用Linq到XML。 – 2011-03-14 19:00:59

+0

@ petronius31:剛剛看到您的更新。三件事:** 1)**您的'using'語句需要包含'XmlNodeList chars = xmlProperties.GetElementsByTagName(「Company」); (0).InnerText.Replace(「{ClientName}」,「Penn Inc。」);',** 2)**您可以使用Linq代替 - 我覺得它更容易,** 3 )**。你會想''xmlProperties.Save'而不是流讀取保存它。 – 2011-03-14 19:35:12

1

如果你要搜索和WordprocessingML文檔中替換文本,有一個相當簡單的算法,您可以使用:

  • 將所有運行分解爲單個字符的運行。這包括具有特殊字符的運行,例如換行符,回車符或硬標籤。
  • 然後很容易找到一組匹配搜索字符串中的字符的運行。
  • 一旦你已經確定了一組相匹配的運行,那麼你可以替換集運行與新創建的運行(其中有包含匹配搜索字符串的第一個字符運行的運行性能)。
  • 用新創建的運行替換單字符運行後,可以合併具有相同格式的相鄰運行。

我寫了一篇博客文章,並記錄了一個屏幕演示,演示了這個算法。

博客文章:http://openxmldeveloper.org/archive/2011/05/12/148357.aspx
屏幕投射:http://www.youtube.com/watch?v=w128hJUu3GM

-Eric