XML 使用 jackson-dataformat-xml 自定义根元素进行反序列化?
XML deserialization using jackson-dataformat-xml custom root element?
所以我现在正在使用 Jackson JSON serialization/deserialization 成功,现在我也在尝试将它用于 XML serialization/deserialization 使用它是 jackson-dataformat-xml-2.3.0.jar
。
我用过
objectmapper.reader(Student.class).withRootName("prefix:student").readValue(jsonString)
将我的 JSON(具有带前缀的根名称)反序列化为 Student
class,这成功了。
现在,我正在尝试将我的 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;
..........................
}
我在 jackson-dataformat-xml
中使用 XmlMapper
反序列化这个:
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 反序列化需要做什么??
尝试将 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 行 => 未声明的命名空间前缀 "prefix")。
我的印象是您无法修改您的 XML 字符串。
但如果可以的话,StaxMan 解决方案更简洁,您应该添加命名空间声明而不是禁用解析器命名空间验证:
<prefix:student xmlns:prefix="http://www.somenamespace.org">
<name>
Jack Jones
</name>
<id>1</id>
</prefix:student>
您的问题是 XML 输入无效,因为它缺少 prefix
的命名空间声明:如果启用了命名空间处理(就像大多数现代 XML 解析器一样) , Jackson XML 模块对此无能为力。
但根据其他答案,通常可以配置底层 XML 解析器以禁用命名空间处理,在这种情况下,整个元素名称仅被视为 "local name" 的一部分,没有命名空间信息会继续维护。
只需确保使用 Woodstox
或 Aalto
Stax 解析器:我认为 JDK 中的一个不支持无命名空间模式。
所以我现在正在使用 Jackson JSON serialization/deserialization 成功,现在我也在尝试将它用于 XML serialization/deserialization 使用它是 jackson-dataformat-xml-2.3.0.jar
。
我用过
objectmapper.reader(Student.class).withRootName("prefix:student").readValue(jsonString)
将我的 JSON(具有带前缀的根名称)反序列化为 Student
class,这成功了。
现在,我正在尝试将我的 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;
..........................
}
我在 jackson-dataformat-xml
中使用 XmlMapper
反序列化这个:
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 反序列化需要做什么??
尝试将 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 行 => 未声明的命名空间前缀 "prefix")。
我的印象是您无法修改您的 XML 字符串。
但如果可以的话,StaxMan 解决方案更简洁,您应该添加命名空间声明而不是禁用解析器命名空间验证:
<prefix:student xmlns:prefix="http://www.somenamespace.org">
<name>
Jack Jones
</name>
<id>1</id>
</prefix:student>
您的问题是 XML 输入无效,因为它缺少 prefix
的命名空间声明:如果启用了命名空间处理(就像大多数现代 XML 解析器一样) , Jackson XML 模块对此无能为力。
但根据其他答案,通常可以配置底层 XML 解析器以禁用命名空间处理,在这种情况下,整个元素名称仅被视为 "local name" 的一部分,没有命名空间信息会继续维护。
只需确保使用 Woodstox
或 Aalto
Stax 解析器:我认为 JDK 中的一个不支持无命名空间模式。