Squeak.ru - шаблоны программирования

JAXB - неупорядочить XML-исключение

Я пытался прочитать большой xml-файл (около 500 МБ). Прежде всего, я использовал xjc с файлом XSD моего XML. Все классы были сгенерированы, как и ожидалось. Пытаясь прочитать файл, я получил эту ошибку: 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>

Я использовал эту ссылку в качестве примера, чтобы создать свой собственный код:

Кто-то знает, как это сделать? Все, что я хочу сейчас, это прочитать огромный файл XML без демаршалирования внешнего объекта XML (проблема пространства кучи Java) и без чтения тег за тегом, получая соответствующее значение, медленный и обезьяний код (не обезьяны из Rise of the Planet обезьян). :П

Большое спасибо.

13.12.2011

  • Можете ли вы поделиться xml и классами и их сопоставлениями jaxb, используемыми здесь? Есть ли класс с аннотацией @XmlRootElement(namespace="", name = "identification") в пакете br.com.mypackage 13.12.2011
  • Арун, в классе Person есть такая аннотация: @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"identification","address","whatever"}) Итак, я думал, что XJC будет делать все эти мелочи, связанные с аннотациями. Может проблема в файле XSD? 13.12.2011
  • Можете ли вы попытаться распечатать содержимое средства чтения событий, прежде чем передавать его демаршаллеру? Похоже, вместо передачи элемента person в корне вы передаете элемент identification. А класс Person должен иметь @XmlType(name = "person", propOrder = {"identification","address","whatever"}). Можете ли вы также указать тип объекта идентификации. 14.12.2011
  • Я сделал тест. Я попытался разобрать объект Identification. Это не работает. Он запускает то же исключение: Вызвано: javax.xml.bind.UnmarshalException: неожиданный элемент (uri:, local:identification). Ожидаемые элементы: ‹(нет)› Я отредактировал файл XML, удалив людей. Я оставил всего 5 человек. С этим небольшим файлом я успешно выполнил операцию демаршалирования, используя самый внешний объект, сгенерированный XJC. Все 5 человек были созданы, как и ожидалось. С этим тестом я не думаю, что это проблема аннотаций. (как я могу отправить вам файл xsd?) 14.12.2011

Ответы:


1

Я предполагаю, что проблема в том, что вы уже использовали <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...
}
13.12.2011
  • Я пробовал. На самом деле я опубликовал дайджест своего кода. Я получаю следующий элемент для каждой итерации цикла while. Во всяком случае, я проверил метод peek (как и вы), но он не работает. Я хотел бы избежать кода, использующего способ переключения для получения каждого поля и его значения. Не могли бы вы прислать мне ссылку на хороший учебник? Может быть, я не понимаю цель функции unmarshal и если она мне нужна. 13.12.2011
  • Всем привет, проблема решена. Вот ссылка на решение: pastebin.com/JQ6uN9Te if (start.getName().getLocalPart() == "person")) { JAXBElement<Person> jax_benef = unmarshaller.unmarshal(eventReader, Person.class); p = jax_benef.getValue(); } Не знаю, почему старый метод не работает (распаковать, используя объект Person вместо JAXBElement). У вас есть какие-то сведения о том, что это не сработало? 14.12.2011
  • @TSoares: я не знаю, но я думаю, что это должно быть как-то связано с объемом контекста, доступным для JAXB, чтобы позволить ему принять решение о том, что делать. (С другой стороны, вам больше не нужно явное приведение, поскольку вы знаете, что получаете.) 15.12.2011

  • 2

    Я решил проблему с этим кодом ниже:

    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 человек в базе данных).

    16.12.2011
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...