2014-03-06 136 views
2

我試圖刪除包含"{Some Text}"的段落。下面的方法就是這樣做的,但我注意到在刪除段落後,剩下的是空的段落元素。如何刪除空的段落元素?

如何以編程方式刪除<w:p />元素?

下面是我最初用來刪除段落。

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(file, true)) 
     { 
      MainDocumentPart mainPart = wordDoc.MainDocumentPart; 
      Document D = mainPart.Document; 

      foreach (Paragraph P in D.Descendants<Paragraph>()) 
      { 
       if (P.InnerText.Contains("{SomeText}")) 
       { 
        P.RemoveAllChildren(); 
        //P.Remove(); //doesn't remove 
       } 
      } 
      D.Save(); 
     } 

這是document.xml中的樣子後記:

<w:p /> 
<w:p /> 
<w:p /> 
<w:p /> 
<w:p /> 
<w:p /> 
<w:p /> 
+1

只是猜測 - 你錯過了一個「不」嗎?正如'if(!P.InnerText.Contains(「{SomeText}」))'? –

+0

這7段是頂級標籤嗎? – rene

+0

是的,他們是頂級標籤@rene –

回答

6

這裏的問題:

 foreach (Paragraph P in D.Descendants<Paragraph>()) 
     { 
      if (P.InnerText.Contains("{SomeText}")) 
      { 
       P.Remove(); //doesn't remove 
      } 
     } 

是你正試圖從集合中刪除的項目,而你仍在迭代中。出於某種奇怪的原因,OpenXML SDK實際上並沒有在這裏拋出異常,它只是默默退出foreach循環。附加一個調試器並逐步完成將向您顯示。解決方法是簡單的:

 foreach (Paragraph P in D.Descendants<Paragraph>().ToList()) 
     { 
      if (P.InnerText.Contains("{SomeText}")) 
      { 
       P.Remove(); //will now remove 
      } 
     } 

通過添加ToList()要複製(淺拷貝)的段落到一個單獨的列表,並通過該列表進行迭代。現在,當您刪除一個段落時,它將從D.Descendants<Paragraph>()集合中刪除,但不會從您的列表中刪除,迭代將繼續。

+0

儘管這似乎是一個合乎邏輯的答案,但很難相信它正在退出循環。 – jn1kk

+0

@jsn:我知道,這很奇怪,但確實如此。如果連接調試器並逐步完成,只要它碰到'P.Remove()'(在第一種情況下),它將跳轉到循環的右括號,然後是下一條語句。它確實應該拋出一個例外,但我想有人對此有所臆斷。 –

+0

你是對的馬特,它確實有效。有一點不相關,但是有沒有辦法遍歷文檔並刪除所有''元素(即當您在創建文檔時按Enter鍵)? –