2013-04-23 2 views
0

긴 파일을 파싱하고 싶지 않은 섹션을 제거하려고합니다. 연구 결과 OpenXml SDK는 doc라는 단어를 통해 조작하고 검색 할 때 가장 쉬운 참조였습니다. 불행하게도 노드를 실행 오브젝트와 같이 할당하려고 시도 할 때 계속해서 NullReferenceExceptions을 얻으므로 일관성있는 것은 아닙니다. 본질적으로, 내 프로그램은 docx 파일을 통해 가서 태그 (ver 1)를 찾은 다음 닫는 태그 (/ ver 1) 사이의 모든 것을 제거해야합니다. 이 부분은 내가 다른 부분으로 작동하는 것으로 보입니다. NullReferenceException이 있는데 MS Word가 사용하는 지저분한 형식화와 관련이 있다고 느낍니다. 그러나 모르겠습니다.DOCX 파일에서 OpenXML을 사용하는 상수 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' 값을 반환합니다. 최종적으로 루트 노드를 나타낼 수 있습니까? 편집 : 왜 당신이 디버거를 통해 실행하고 왜/실패 이유를보고, 또는 적어도 우리에게 더 많은 정보를 제공합니다. –

+0

어떤 라인에서 예외가 발생합니까? – Romoku

+0

모든 것을 try-catch로 둘러 싸고 오류를 게시 할 수 있습니까? – devilfish17

답변

1

내가 아니다 당신이 여기서하려고하는 것이 무엇인지 확실하지만 ...

본문에서 정적 인 아동 목록을받습니다.

삭제 된 자식을 반복 처리합니다. 그런 다음 이미 제거 된 자식을 RemoveAllChildren()으로 삭제한다고합니다.

이 오류 논리는 말할 것도 없습니다. 그것은 아마 Text 요소되지 않을 것 때문에 다른 절에서

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

는 endelems 아마하는 Run하는 부모가되지 않습니다.

--- 편집 --- 의사

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을 사용하는 것에 익숙하다. 그래서 나는 그것을 날개 짓하고있다. 그래서 OpenXmlElements의 IEnumerable은 예를 들어 일관된 노드를 나타내며, 모든 노드는 이거나 항상 다른 노드입니까? 내가하려고하는 것에 관해서, 나는 두 개의 태그 (Ver1)와 (/ Ver1) 사이의 모든 텍스트를 제거하려고 시도하고있다. 이 작업을 수행하는 더 좋은 방법이 있습니까? – user1704863

+0

@ User1704863 내 편집을 참조하십시오. – jn1kk

+0

감사! 그러나 이것이 유용하기 때문에, 당신은 Run과 Paragraph에 대해 foreach를 사용하여 무엇을했는지 요약 할 수 있습니다. 다시 감사합니다 – user1704863

관련 문제