2013-08-26 86 views
1

看看這篇文章的結尾,用文本框添加這個問題!如何用特殊字符替換XML文檔中的文本?

用這種方法我想打開一個文檔,替換一些文本,然後讓它獨自一人。它的作品,這是值得驕傲的東西。 :d

public static void replaceInOpenXMLDocument(string pfad, string zuErsetzen, string neuerString) 
     { 
      using (WordprocessingDocument doc = WordprocessingDocument.Open(pfad, true)) 
      { 
       var res = from bm in doc.MainDocumentPart.Document.Body.Descendants() 
          where bm.InnerText != string.Empty && bm.InnerText.Contains(zuErsetzen) && bm.HasChildren == false 
          select bm; 

       foreach (var item in res) 
       { 
        item.InsertAfterSelf(new Text(item.InnerText.Replace(zuErsetzen, neuerString))); 
        item.Remove(); 
       } 
       doc.Close(); 
      } 
     } 

但它只能在更換無特殊字符。 例如:

OS將與視窗9000

[OS]會留下,因爲它是被替換。

CASE 1:

在文檔:

You use os for whatever purpose you've got.

replaceInOpenXMLDocument("C:\NSA\suspects.docx", "os", "Win 2000"); 

會導致這樣的:

You use Win 2000 for whatever purpose you've got.

CASE 2:

有特殊字符...

You use [os] for whatever purpose you've got.

replaceInOpenXMLDocument("C:\NSA\suspects.docx", "[os]", "Win 2000"); 

...它只是不理我:

You use [os] for whatever purpose you've got.

我試了幾個特殊字符()[] {}等,但他們永遠不會被取代。

有什麼我忘記了嗎?或者它是無法用這種方法替換特殊字符? 如果是這樣,我只需要一個簡單的解決方法。

有沒有人幫助我的絕望? :)

SOLUTION /加入1:

感謝Flowerking爲!這是我現在使用的代碼:

public static void replaceInOpenXMLDocument(string pfad, string zuErsetzen, string neuerString) 
     { 
      using (WordprocessingDocument doc = WordprocessingDocument.Open(pfad, true)) 
      { 
       SimplifyMarkupSettings settings = new SimplifyMarkupSettings 
       { 
        NormalizeXml = true, // Merges Run's in a paragraph with similar formatting 

       }; 
       MarkupSimplifier.SimplifyMarkup(doc, settings); 

       //zuErsetzen = new XElement("Name", zuErsetzen).Value; 
       var res = from bm in doc.MainDocumentPart.Document.Body.Descendants() 
          where bm.InnerText != string.Empty && bm.InnerText.Contains(zuErsetzen) && bm.HasChildren == false 
          select bm; 
       // bm.InnerText.Contains(zuErsetzen) 

       foreach (var item in res) 
       { 
        item.InsertAfterSelf(new Text(item.InnerText.Replace(zuErsetzen, neuerString))); 
        item.Remove(); 
       } 

       doc.Close(); 
      } 
     } 

(此代碼將工作與在其正常的文字正常文檔!)

SOLUTION /添加2: 如果你想要取代文本框中的文字,我不得不做一些小的解決方法。 文本框被聲明爲圖片,所以上面的代碼不會觸及它。

我發現了一個額外的類(link),它甚至可以通過文本框搜索。 ZIP下載包括一個exmaple程序,易於理解。

+2

你的榜樣輸入/輸出是不太清楚。請更具體地說明其當前正確/不正確的行爲以及您希望不正確的行爲。 – tnw

+0

對問題沒有清楚的認識! – Irfan

+0

對不起!讓我只是編輯這個給你... – Trollwut

回答

2

發生這種情況,因爲當文本包含特殊字符看起來像打開XML詞通常會產生:

<w:r w:rsidRPr="00316587"> 
    <w:rPr> 
     <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" /> 
     <w:color w:val="823125" /> 
     <w:sz w:val="20" /> 
     <w:szCs w:val="20" /> 
     <w:lang w:eastAsia="en-GB" /> 
    </w:rPr> 
    <w:t>[</w:t> 
    </w:r> 
    <w:proofErr w:type="gramStart" /> 
    <w:r w:rsidRPr="00316587"> 
    <w:rPr> 
     <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" /> 
     <w:color w:val="823125" /> 
     <w:sz w:val="20" /> 
     <w:szCs w:val="20" /> 
     <w:lang w:eastAsia="en-GB" /> 
    </w:rPr> 
    <w:t>text-to-replace</w:t> 
    </w:r> 
    <w:proofErr w:type="gramEnd" /> 
    <w:r w:rsidRPr="00316587"> 
    <w:rPr> 
     <w:rFonts w:ascii="Consolas" w:hAnsi="Consolas" w:eastAsia="Times New Roman" w:cs="Consolas" /> 
     <w:color w:val="823125" /> 
     <w:sz w:val="20" /> 
     <w:szCs w:val="20" /> 
     <w:lang w:eastAsia="en-GB" /> 
    </w:rPr> 
    <w:t>]</w:t> 
    </w:r> 
</w:p> 

文本[text-to-replace]創建上面顯示的Open XML。 (請注意,情況並非總是如此,可能取決於您使用的客戶端)。

通過您的代碼的外觀doc.MainDocumentPart.Document.Body.Descendants()您正在採取所有OpenXmlPart類型後裔爲整個文檔的身體,並試圖取代逐一迭代的文本,使實際文本在一個部分和兩個特殊部分中的特殊字符。因此,代碼不能滿足要求。

可能有不同的方法來解決這個問題。

解決方案:

一個很好(我的優選的)解決方案將是正常化使用標記簡化器從OpenXml Powertools的XML,這將標準化開放XML標記來連接段落中的文本,以簡化編程工作。

示例代碼:

using (WordprocessingDocument doc = 
      WordprocessingDocument.Open("Test.docx", true)) 
{ 
     SimplifyMarkupSettings settings = new SimplifyMarkupSettings 
     { 
      NormalizeXml = true, // Merges Run's in a paragraph with similar formatting 

     }; 
     MarkupSimplifier.SimplifyMarkup(doc, settings); 
    } 

請參閱我的回答here更多信息使用MarkupSimplifier

希望這有助於:)

+0

啊,是的,我可以跟着你。我遵循README文件中的安裝說明,但無法完成它。我得到了缺失的'System.Management.Automation'工作,但我現在陷入了另一個錯誤:類型或命名空間「OutputTypeAttribute」無法找到(德語翻譯)。你有解決方案嗎?此外,我現在正在搜索這個問題。 :) – Trollwut

+0

是否有可能我已經(雖然PowerShell的新安裝)該DLL的舊版本?如果是這樣:如何更新它? – Trollwut

+0

我試圖用PowerShell中的幾個命令(例如'Copy([PSObject] .Assembly.Location)C:\')複製這個DLL,但是我解決不了我的問題。互聯網上的人們說,他們可能會得到一個大小約3 MB的版本,但我的總是2.6 MB。 (只是寫這個通知你我的嘗試。) – Trollwut