首页 文章

JAXB - 解组XML异常

提问于
浏览
2

我试过读一个大的xml文件(类似于500MB) . 首先,我使用xjc和我的XML的XSD文件 . 所有类都按预期生成 . 试图读取文件我遇到了这个错误:javax.xml.bind.UnmarshalException:意外的元素 .

这是我的代码:

(......)

JAXBContext context = JAXBContext.newInstance("br.com.mypackage");
Unmarshaller unmarshaller = context.createUnmarshaller();
File f = new File("src/files/MyHuge.CNX");
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
InputStream in = new FileInputStream(f);
XMLEventReader eventReader = inputFactory.createXMLEventReader(in);
Person p = null;
int count = 0;
while (eventReader.hasNext()) {
   XMLEvent event = eventReader.nextEvent();
   if (event.isStartElement()) {
      StartElement startElement = event.asStartElement();
      if (startElement.getName().getLocalPart() == ("person")) {
         p = (Person) unmarshaller.unmarshal(eventReader);
      }
   }
}

问题在于解组操作 .

Caused by: javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"identification"). Expected elements are <{}messageAll>

我使用此链接作为示例来制作我自己的代码:JAXB - unmarshal OutOfMemory: Java Heap Space

有人有线索这样做吗?我现在想要的只是阅读一个巨大的XML文件而不用解组XML的外部对象(java堆空间问题)并且不用标签读取标签获取相应的值,慢速和猴子代码(不是行星的崛起的猴子)猿猴) . :P

非常感谢 .

2 回答

  • 1

    我'm guessing that the problem is you'已经从事件流中消耗了 <person> ,因此JAXB不知道它在做什么;它需要那个元素,所以它可以构建对象 . 因此,我怀疑你需要查看流来决定是否消费(和丢弃)或解组:

    while (eventReader.hasNext()) {
       XMLEvent event = eventReader.peek();
       if (event.isStartElement()) {
          StartElement startElement = event.asStartElement();
          if (startElement.getName().getLocalPart() == ("person")) {
             p = (Person) unmarshaller.unmarshal(eventReader);
             continue; // Assume you've done something with p; go round loop again
          }
       }
       eventReader.nextElement(); // Discard...
    }
    
  • 1

    我用下面的代码解决了这个问题:

    public List<Person> testeUnmarshal() {
      List<Person> people = new ArrayList<Person>();
      Person p = null;
      try {
        JAXBContext context = JAXBContext.newInstance(Person.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        File f = new File(FILE_PATH);
        XMLInputFactory inputFactory = XMLInputFactory.newInstance();
        XMLEventReader eventReader = inputFactory.createXMLEventReader(new FileInputStream(f));
        while (eventReader.hasNext()) {
          XMLEvent event = eventReader.peek();
          if (event.isStartElement()) {
            StartElement start = event.asStartElement();
        if (start.getName().getLocalPart() == "person")) {
              JAXBElement<Person> jax_b = unmarshaller.unmarshal(eventReader, Person.class);
          p = jax_b.getValue();
        }
          }
          eventReader.next();
        }
      } catch (Exception e) {
      }
      return persons;
    }
    

    我可以使用循环内的计数来控制内存中的对象数量(对于数据库中的1000人提交) .

相关问题