2013-04-23 61 views
0

我試圖通過一個冗長的文件解析並刪除我不想要的部分。從研究看來,OpenXml SDK是操縱和搜索word doc最簡單的參考。不幸的是,它並不總是一致的,因爲在嘗試將節點分配給運行對象時,我總是收到NullReferenceExceptions。實質上,我的程序應該通過docx文件並找到標籤(版本1),然後刪除它與結束標籤(/版本1)之間的所有內容。這似乎只適用於其他部分的某些部分,我得到NullReferenceException,我覺得它與MS Word使用的混亂格式有關,但我不知道。在DOCX文件上使用OpenXML的Constant NullReference異常

下面是特定部分的代碼,如果有人可以幫助我欣賞它。圍繞整個事情

IEnumerable<OpenXmlElement> elem = main.Document.Body.Descendants().ToList(); 
foreach (OpenXmlElement elems in elem) 
{ 
    if (elems is Text && elems.InnerText == s_Ver1)// s_Ver1 = "(Ver 1)" 
    { 
     Run run = (Run)elems.Parent; 
     Paragraph p = (Paragraph)run.Parent; 
     p.RemoveAllChildren(); 
     p.Remove(); 

     foreach (OpenXmlElement endelems in elem) 
     { 
     if (endelems is Text && elems.InnerText == e_Ver1)//e_Ver1 = "(/Ver1)" 
     { 
      run = (Run)endelems.Parent; 
      p = (Paragraph)run.Parent; 
      p.Remove(); 
      break; 
     } 

     else 
     { 
      Run d_Run = (Run)endelems.Parent; 
      Paragraph d_p = (Paragraph)d_Run.Parent; 
      d_p.RemoveAllChildren(); 
      d_p.Remove();*/ 

      try 
      { 
       endelems.Remove(); 
      } 

      catch(Exception err) 
      { 
       MessageBox.Show(err.ToString()); 
      } 
      } 
     } 
    } 
} 

編輯

嘗試捕捉與代碼中(圍繞endelems.remove())

System.InvalidOperationException: The Parent of this element is Null 
//it also says line 141 but I'm not sure how to get line numbering in vs2010 

嘗試捕捉錯誤

System.NullReferenceException: Object reference not set to an instance of an object 
//line 114 which would be Paragraph p = (Paragraph)run.Parent; line 
+0

我猜某處'elems.Parent'或'endelems.Parent'返回'null'值。它們有可能最終代表根節點嗎?編輯:你爲什麼不運行調試器,看看它在哪裏/爲什麼失敗,或者至少爲我們提供更多信息。 – 2013-04-23 21:02:29

+0

哪些線路例外? – Romoku 2013-04-23 21:05:32

+0

你可以用try-catch來包圍整個事物併發布錯誤嗎? – devilfish17 2013-04-23 23:55:05

回答

1

我不是很確定你在這裏試圖做什麼,但...

你從身體中得到一個靜態的兒童列表。

您遍歷可能已刪除的子項。然後致電刪除已使用RemoveAllChildren()刪除的孩子。

更不用說這個錯誤的邏輯。

if (endelems is Text && elems.InnerText == e_Ver1)//e_Ver1 = "(/Ver1)" 
{ 
    ... 
else 
{ 
    Run d_Run = (Run)endelems.Parent; 
} 

在else子句,endelems很可能將沒有父母這是一個Run,因爲它可能不會是一個Text元素。

---編輯---僞

IEnumerable<Text> elems = wd.MainDocumentPart.Document.Body.Descendants<Text>(); 
foreach (Text elem in elems) 
{ 

    if(elem.InnerText.Equals("Ver 1")) 
    { 
     IEnumerable<OpenXmlElement> afterelems = elem.ElementsAfter(); 
     foreach(OpenXmlElement openelem in afterelems) 
     { 
      if(openelem is Text && ((Text)openelem).InnerText.Equals("Ver 2")) 
      { 
       break; 
      } else if(openelem is Text) { 
       openelem.Remove(); 
      } 
     } 
     break; 
    } 

} 

foreach (Run run in wd.MainDocumentPart.Document.Body.Descendants<Run>().Where(run => run.Descendants<Text>().Count() == 0 && run.Descendants<Break>().Count() == 0)) 
{ 
    run.Remove(); 
} 

foreach (Paragraph par in wd.MainDocumentPart.Document.Body.Descendants<Paragraph>().Where(par => par.Descendants<Run>().Count() == 0 && par.Descendants<Table>().Count() == 0)) 
{ 
    par.Remove(); 
} 
+0

好吧,我是新來的使用OpenXml,所以我有點wing it它。因此,我得到的IEXumerable的OpenXmlElements,做代表一個一致的節點,例如,他們的所有節點,或者它們總是不同?至於我想要做的,我試圖刪除兩個標籤(Ver1)和(/ Ver1)之間的所有文本。有一個更好的方法嗎? – user1704863 2013-04-24 14:26:27

+0

@ User1704863看到我的編輯。 – jn1kk 2013-04-24 14:59:34

+0

謝謝!但像這樣有用,是否可以總結一下你對Run和Paragraph的foreach做了什麼。再次感謝 – user1704863 2013-04-24 15:39:01

相關問題