有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JAXB解组XML异常

我试图读取一个大的xml文件(大约500MB)。 首先,我将xjc与XML的XSD文件一起使用。所有类都按预期生成。 尝试读取文件时,我遇到了以下错误:javax。xml。绑定解组异常:意外元素

这是我的密码:

(……)

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. # 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人提交)

  2. # 2 楼答案

    我猜问题是您已经从事件流中使用了<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...
    }