我正在使用一些.xml并偶然发现从未见过的异常。这是破碎的代码:
public class UnmarshallProva {
public static void main(String[] args) {
JAXBContext jaxbCx;
Unmarshaller mavByXml;
FileReader fr;
XMLInputFactory xif;
XMLEventReader xer;
int mavv = 0;
try {
jaxbCx = JAXBContext.newInstance(MavType.class);
mavByXml = jaxbCx.createUnmarshaller();
fr = new FileReader(new File(args[0]));
xif = XMLInputFactory.newFactory();
xer = xif.createXMLEventReader(fr);
while(xer.hasNext()) {
XMLEvent xe = xer.nextEvent();
if(xe.isStartElement()) {
if(xe.asStartElement().getName().getLocalPart().equals("mav")) {
if(xer.peek() != null) {
mavByXml.unmarshal(xer, MavType.class).getValue();
}
mavv++;
}
}
}
System.out.println(UnmarshallProva.class.getName()+" DONE. "+mavv+" MAv.");
} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
}
}
}
类MavType
由xjc
命令生成。当XMLEventReader
找到第一个<mav>
标记时,它会尝试取消编组并返回此异常:
java.lang.IllegalStateException: reader must be on a START_ELEMENT event, not a 4 event
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:449)
at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:430)
at prove.UnmarshallProva.main(UnmarshallProva.java:38)
仍然令人费解,为什么这不起作用。
答案 0 :(得分:3)
XMLEventReader
没有获取当前事件的方法,因此当您将其传递给Unmarshaller
时,它会要求下一个事件(它可以&#39; t通过XMLEvent
获取您已经要求的xer.nextEvent()
。
您可以更改while
逻辑以执行以下操作:
while(xer.hasNext()) {
XMLEvent xe = xer.peek(); // CHANGE
if(xe.isStartElement()) {
if(xe.asStartElement().getName().getLocalPart().equals("mav")) {
// if(xer.peek() != null) {
mavByXml.unmarshal(xer, MavType.class).getValue();
// }
mavv++;
}
}
// NEW
if(xer.hasNext()) {
xer.nextTag();
}
}
我建议您使用XMLStreamReader
来获取您正在寻找的行为。我在我的博客上有一个完整的例子,你可能会发现它很有用: