Десериализация XML с использованием настраиваемого корневого элемента jackson-dataformat-xml?

Итак, я успешно использую Jackson для сериализации / десериализации JSON до сих пор, теперь я также пытаюсь использовать его для сериализации / десериализации XML, используя его jackson-dataformat-xml-2.3.0.jar.

я использовал

objectmapper.reader(Student.class).withRootName("prefix:student").readValue(jsonString)

десериализовать мой JSON (с корневым именем с префиксом) в класс Student, который работал успешно.

Теперь я пытаюсь десериализовать свою XML-строку (с корневым именем с префиксом) до Student:

XML:

<prefix:student>
  <name>
    Jack Jones
  </name>
  <id>1</id>
</prefix:student>

Мое POJO:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "name",
        "id",
        ....
    })
    @XmlRootElement(name = "student")
    public class Student
    {

        protected String name;
        BigInteger id;  
..........................
    }

Я десериализировал это, используя XmlMapper в jackson-dataformat-xml вот так:

xmlMapper.reader(Student.class).withRootName("prefix:student").readValue(xmlString)

У меня следующее исключение:

java.io.IOException: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwXmlAsIOException(StaxUtil.java:24)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:473)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:26)
    at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:844)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2091)

Caused by: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    at com.ctc.wstx.sr.InputElementStack.resolveAndValidateElement(InputElementStack.java:507)
    at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2977)
    at com.ctc.wstx.sr.BasicStreamReader.handleRootElem(BasicStreamReader.java:2098)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2078)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._initializeXmlReader(XmlFactory.java:581)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:471)
    ... 6 more

Что мне нужно сделать для десериализации XML с настраиваемым корневым именем?


person Siddharth Trikha    schedule 02.09.2016    source источник
comment
Имя вашего корневого элемента не student, как определено здесь: @XmlRootElement(name = "student")!   -  person My-Name-Is    schedule 05.09.2016
comment
@ My-Name-Is: Я отредактировал вопрос. В основном у меня есть префикс пространства имен внутри корневого имени. Таким образом, корневое имя student становится prefix:student   -  person Siddharth Trikha    schedule 05.09.2016


Ответы (2)


Ваша проблема в том, что ввод XML недействителен, поскольку в нем отсутствует объявление пространства имен для prefix: если обработка пространства имен включена (как в большинстве современных синтаксических анализаторов XML), модуль Jackson XML ничего не может с этим поделать.

Но в соответствии с другим ответом часто можно настроить базовый синтаксический анализатор XML, чтобы отключить обработку пространства имен, и в этом случае все имя элемента просто считается частью «локального имени», и информация о пространстве имен не будет поддерживаться.

Просто убедитесь, что вы используете парсеры Woodstox или Aalto Stax: я думаю, что один в JDK не поддерживает режим без пространства имен.

person StaxMan    schedule 06.09.2016
comment
У меня такая же проблема, у меня сериализованный класс с JacksonXmlModule и XmlMapper, с `@JacksonXmlProperty (localName = namespaceprefix: localname)` есть ли способ добавить префикс пространства имен с локальным именем, чтобы я не получил com.fasterxml.jackson.core.JsonParseException: Undeclared namespace prefix с Модуль Jackson XML сейчас !. - person Raghu DV; 14.12.2017

Попробуйте настроить свой XmlMapper так, чтобы он игнорировал пространства имен:

XMLInputFactory input = new WstxInputFactory();
input.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
XmlMapper xmlMapper = new XmlMapper(new XmlFactory(input, new WstxOutputFactory()));

Кроме того, вам, возможно, придется изменить свой @XmlRootElement(name= "student") на @XmlRootElement(name= "prefix:student")

Редактировать :

Как сказал StaxMan, ваша проблема связана с тем, что вы используете префикс, который не был объявлен.

Это можно сделать из журнала, который вы нам предоставили (Строка 1 и Строка 9 => Префикс необъявленного пространства имен «префикс»).

У меня создалось впечатление, что вы не можете изменить свою строку XML.

Но если вы можете, решение StaxMan чище, и вам следует добавить объявление пространства имен вместо отключения проверки пространства имен парсера:

<prefix:student xmlns:prefix="http://www.somenamespace.org">
  <name>
    Jack Jones
  </name>
  <id>1</id>
</prefix:student>
person Dimpre Jean-Sébastien    schedule 06.09.2016