【问题标题】:StAX - XMLEventReader unexpected behaviorStAX - XMLEventReader 意外行为
【发布时间】:2017-04-04 16:04:06
【问题描述】:

我刚刚尝试使用 StAX 来解析一些琐碎的 XML 文档

<?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'}]

所以我的问题是 W-H-Y-YYYYYY?这绝对是不直观的。这不是 JAXB。不是任何其他对象映射器。如果我自己做所有的工作,为什么类名很重要?

附:最初是Employee.class&lt;employee/&gt; 的问题,但我简化了测试用例以强调类名。

【问题讨论】:

    标签: java xml stax


    【解决方案1】:

    您必须检查员工作为结束节点,而不是 "foo"

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

    【讨论】:

    • 糟糕,这是我第一次向 SO 发布问题以纠正拼写错误。它让我想把头撞在墙上。 :(谢谢。
    • 别担心,明显的错误很难确定,有时你只需要另一双眼睛。
    猜你喜欢
    • 2019-06-19
    • 2013-06-02
    • 2017-05-12
    • 1970-01-01
    • 2017-03-10
    • 2019-05-01
    • 2011-07-15
    • 2011-04-27
    • 2019-12-07
    相关资源
    最近更新 更多