2017-04-04 10 views
1
난 그냥 해봤

몇 가지 사소한 XML 문서StAX를 - XMLEventReader의 예기치 않은 동작

<?xml version="1.0"?> 
<root> 
    <Employee> 
     <name>John</name> 
    </Employee> 
    <Employee> 
     <name>Lisa</name> 
    </Employee> 
</root> 

을 구문 분석 할 경우 StAX를 활용 ...하지만 나를 미치게 만드는 문제에 직면했다. 다음은 코드입니다.

public class Foo { 

    public String name; 

    @Override 
    public String toString() { 
     return "Foo{" + "name='" + name + '\'' + '}'; 
    } 
} 

public class StAXParserTest { 

    @Test 
    public void testFoo() throws Exception { 
     List<Foo> result = new ArrayList<>(); 
     XMLEventReader eventReader = XMLInputFactory 
       .newInstance() 
       .createXMLEventReader(getResourceAsStream("example.xml")); 
     while (eventReader.hasNext()) { 
      XMLEvent event = eventReader.nextEvent(); 
      if (event.isStartElement()) { 
       StartElement startElem = event.asStartElement(); 
       switch (startElem.getName().getLocalPart()) { 
        case "Employee": 
         result.add(parseFoo(eventReader)); 
         break; 
       } 
      } 
     } 
     System.out.println(result); 
    } 

    private static Foo parseFoo(XMLEventReader eventReader) throws XMLStreamException { 
     Foo foo = new Foo(); 
     while (true) { 
      XMLEvent event = eventReader.nextEvent(); 
      if (event.isStartElement()) { 
       switch (event.asStartElement().getName().getLocalPart()) { 
        case "name": 
         foo.name = eventReader.nextEvent().asCharacters().getData(); 
         break; 
       } 
      } 

      if (event.isEndElement() && event.asEndElement().getName().getLocalPart().equals("Foo")) { 
       return foo; 
      } 
     } 
    } 

    private InputStream getResourceAsStream(String filename) throws URISyntaxException { 
     return this.getClass().getClassLoader().getResourceAsStream(filename); 
    } 
} 

아무 문제가 없습니다. 그러나 테스트를 실행하면 다음 오류가 발생합니다.

java.util.NoSuchElementException 
    at com.sun.xml.internal.stream.XMLEventReaderImpl.nextEvent(XMLEventReaderImpl.java:88) 
    at stax.StAXParserTest.parseFoo(StAXParserTest.java:40) 
    at stax.StAXParserTest.testFoo(StAXParserTest.java:29) 

나는 그 원인을 알아 내기 위해 한 시간을 보냈습니다.

[Employee{name='John'}, Employee{name='Lisa'}] 

그래서 제 질문은 왜-YYYYYY이다 (즉, foo.class 위가 Employee.class로 변경해야한다) XML 태그 이름과 정확하게 일치해야하는 문제 POJO 클래스 이름을 해결하고 작동보다하기 위해 ? 그것은 절대적으로 비 직관적입니다. 이것은 JAXB가 아닙니다. 다른 객체 매퍼가 아닙니다. 왜 내가 수업을 왜 중요하게 생각하는지보다 나 자신이 모든 일을한다면?

P. 처음에는 Employee.class<employee/> 문제 였지만 클래스 이름을 강조하기 위해 테스트 케이스를 단순화했습니다.

답변

2

"foo"이 아닌 직원을 종료 노드로 확인해야합니다.

 if (event.isEndElement() && event.asEndElement() 
      .getName().getLocalPart() 
      .equals("Employee")) { 
      return foo; 
     } 
+0

죄송하지만, 오타를 수정하기 위해 처음으로 질문을 게시했습니다. 그것은 내 머리를 벽에 부딪치게하고 싶다. 고마워요. – enzo

+1

걱정하지 마세요. 분명한 오류를 정하기가 어렵습니다. 때로는 또 다른 쌍의 눈이 필요합니다. – minus