2017-04-04 55 views
1

我只是試着使用的StAX解析一些瑣碎的XML文檔StAX的 - XMLEventReader的意外行爲

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

...但面臨的一個問題,這讓我瘋了。這裏是代碼:

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) 

我花了一個小時找出原因。爲了解決這個問題POJO類名必須是完全一樣的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

糟糕,這是我第一次發佈問題以糾正錯字錯誤。這讓我想把我的頭撞在牆上。 :(謝謝。 – enzo

+1

別擔心,明顯的錯誤難以確定,有時你只需要另一雙眼睛。 – minus