2017-10-05 7 views
0

저는 Java에 익숙하지 않지만 학교에서이 프로젝트를하고 있습니다. 4GB의 XML 파일 (위키피디아 덤프)을 파싱해야합니다. 나는 StAX를 사용하고 내 코드는 400,000 라인 (거의 50MB) 이상을 위해 성공적으로 실행하지만이 오류가 발생합니다. 스레드 "메인"java.lang.IllegalStateException에현재 상태 END_ELEMENT가 CHARACTERS, COMMENT, CDATA, SPACE, ENTITY_REFERENCE 및 getText()에 유효한 DTD 중 하나가 아닙니다.

예외 : 현재 END_ELEMENT 상태에서, statesCHARACTERS, 코멘트 중하지 CDATA, 공간 ENTITY_REFERENCE, 에서 gettext에()에 대한 DTD 유효 com.sun.org .apache.xerces.internal.impl.XMLStreamReaderImpl.getText tagremoving1.TagRemoving1.main (TagRemoving1.java:65)에서 (XMLStreamReaderImpl.java:1081)

내가 gettext에을 (사용할 때 어디 선가 읽기) 내가 말아야 내가 했으므로 null 또는 빈 요소를 확인하십시오. 그런 다음 더 멀리 나아가지만 같은 오류로 다시 멈 춥니 다. 나는 거의 모든 곳을 들여다 보았다. 나는 틀린 것을 모른다.

XMLInputFactory factory = XMLInputFactory.newInstance(); 
    File file = new File("source.xml"); 
    FileInputStream fileReader = new FileInputStream(file);  
    factory.setProperty(XMLInputFactory.IS_COALESCING, true); 
      factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,true); 
      factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,false); 
    PrintWriter writer1 = new PrintWriter("result.txt", "UTF-8"); 

    XMLStreamReader reader = factory.createXMLStreamReader(fileReader); 
    int counter = 1; 
    while(reader.hasNext()){ 

     if(reader.next() == 1){ //If it is START_ELEMENT 
      String name = reader.getLocalName(); 
      switch(name){ 
       case "page": 
        writer1.println("\r\npage" + counter + ":"); 
        counter++; 
        break; 

       case "title": 
        reader.next(); 
        if(reader != null && !"".equals(reader.toString())) 
          writer1.println("Title: " + reader.getText()); 
        break; 

       case "text": 
        reader.next(); 
        if(reader != null && !"".equals(reader.toString())) 
         writer1.println("Text: " + reader.getText()); 
        break; 

       default: 
        break; 
      } 
     } 

    } 
    writer1.flush(); 
    writer1.close(); 

어떤 제안 : 이 내 코드?

+0

오류가 발생한 지점에서 XML을 표시 할 수 있습니까? 그렇지 않으면, 모든 사람이 무슨 일이 일어나고 있는지 짐작할 수 있습니다. –

+0

정확하게 "단어"의 중간에 주제의 중간에 멈 춥니 다 (위키피디아 기사를 언급했듯이) "단어"의 중간에 있습니다. 텍스트가 페르시아어이므로 도움이되는지 확실하지 않습니다. 그것은 그것이 메모리 문제 일 수 있습니까? 왜냐하면 그것은 큰 기사이기 때문입니다. - @ DawoodibnKareem – Shireen

+0

나는 그것이 정말로 기억 문제인지 의심 스럽다. 문서 중간에 잘못된 XML이있을 가능성이 훨씬 큽니다. 문서에서 어디에서 이런 일이 발생하는지 파악할 수 있다면 XML을 살펴보고 잘못된 것을 볼 수 있는지 확인하는 것이 좋습니다. 문제가 발생한 부분을 파악하는 데 도움이되도록 문서의 관리 가능한 부분에서 문제가 발생할 때까지 문서의 절반을 제거한 다음 나머지 절반은 제거하는 등의 조치를 취할 수 있습니다. –

답변

0

글쎄, 알아 냈어!

reader.hasText()을 'if'로 추가하면 모든 것이 정상입니다. 코드는 다음과 같습니다.

case "text": 
    reader.next(); 
    if(reader != null && !"".equals(reader.toString()) && reader.hasText())      
    writer1.println("Text: " + reader.getText()); 
    break;