2017-04-04 1 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) 

私は原因を突き止めるのに1時間を費やしました。問題のPOJOクラス名を解決するためにEXACTLY XMLタグ名と同じ(すなわちFOO.CLASSがEmployee.classに名前を変更する必要があります)、それが作品に比べなければなりません:

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

だから私の質問は、なぜ、YYYYYYです?それは絶対に直感的ではありません。これはJAXBではありません。他のオブジェクトマッパーではありません。なぜクラス名が重要なのか、私は自分ですべての仕事をしていますか?

P.S.当初はEmployee.class<employee/>の問題でしたが、クラス名を強調するためにテストケースを簡略化しました。

答えて

2

"foo"ではなく、終了ノードとして従業員を確認する必要があります。

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

誤って入力ミスを修正するために私はSOに質問を投稿しました。それは私が壁に向かって私の頭を強打したい。 :(ありがとうございます。 – enzo

+1

明らかなエラーは簡単に取り除くことは困難です。 – minus