gpt4 book ai didi

java - 使用 Jackson 反序列化 XML 以从 XSD 生成选择时出错

转载 作者:行者123 更新时间:2023-12-01 19:52:40 27 4
gpt4 key购买 nike

我当前正在尝试将传入的 XML 反序列化为从 XSD 生成的对象。遗憾的是,在尝试反序列化为生成的选择元素时似乎存在问题。我已经尝试了很多东西,我什至只是实现了非常基本的示例,如 here 所示。 。每次我都会遇到同样的异常。实现如下:

public static void main(final String[] args) throws IOException {
final String xml =
"<Foo> \n" +
" <A> 1 </A>\n" +
" <B> 2.5 </B>\n" +
"</Foo>";

final XmlMapper xmlMapper = new XmlMapper();
final Foo foo = xmlMapper.readValue(xml, Foo.class);
}

public static class Foo {

@XmlElementRefs({
@XmlElementRef(name = "A", type = Integer.class),
@XmlElementRef(name = "B", type = Float.class)
})
public List items;
}

在我的应用程序中,每个元素都被赋予基本的 JAXBElement 类型,而不是显式类型。我得到的异常:

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "A" (class x.y.z.Application$Foo), not marked as ignorable (one known property: "items"])
at [Source: (StringReader); line: 2, column: 15] (through reference chain: x.y.z.Application$Foo["A"])

看起来他只是在寻找具有给定名称的字段,并尝试将值设置为此,这当然不存在。

我在这里看到了类似的问题,其中答案指出您应该添加一个配置来忽略未知,这不是我想要的。我希望列表最后包含两个元素,即两个数字。

我还看到了一个名为 Simplify 的扩展,以便为每个选择元素生成一个列表字段。在我的用例中,我实际上更愿意将所有内容添加到单个列表中。

最佳答案

@XmlElements 的 Javadoc您链接到的内容基于 JAXB。例如。直接使用 JAXB 解析(反编码)和序列化(编码)该 XML:

public static void main(final String[] args)
throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);

String xml =
"<Foo> \n" +
" <A> 1 </A>\n" +
" <B> 2.5 </B>\n" +
"</Foo>";

StringReader sr = new StringReader(xml);
Foo foo = (Foo) jaxbContext.createUnmarshaller().unmarshal(sr);
System.out.println(foo.items);

StringWriter sw = new StringWriter();
jaxbContext.createMarshaller().marshal(foo, sw);
System.out.println(sw);
}

@XmlRootElement(name = "Foo")
public static class Foo {

@XmlElements({
@XmlElement(name = "A", type = Integer.class),
@XmlElement(name = "B", type = Float.class)
})
public List items;
}

输出:

[1, 2.5]
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Foo><A>1</A><B>2.5</B></Foo>

上述问题中的示例有一些调整:

  • @XmlRootElement需要允许开始 <Foo>元素
  • 它需要是 @XmlElement(s)而不是@XmlElementRef(s)对于基本IntegerFloat类型
<小时/>

你说得对, jackson 也应该能够使用这些注释。为此,您还需要启用该模块:xmlMapper.registerModule(new JaxbAnnotationModule())

然而,对于这个例子来说,这仍然不能很好地结合在一起。例如,再次尝试双向:

public static void main(final String[] args)
throws IOException {
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(new JaxbAnnotationModule());

Foo foo = new Foo();
foo.items = Arrays.asList(1, 2.5f);

String xml = xmlMapper.writeValueAsString(foo);
System.out.println(xml);

xml =
"<Foo> \n" +
" <A> 1 </A>\n" +
" <B> 2.5 </B>\n" +
"</Foo>";

foo = xmlMapper.readValue(xml, Foo.class);
}

public static class Foo {

@JacksonXmlElementWrapper(useWrapping = false)
@XmlElements({
@XmlElement(name = "A", type = Integer.class),
@XmlElement(name = "B", type = Float.class)
})
public List items;
}

...返回此...

<Foo><items>1</items><items><B>2.5</B></items></Foo>

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "A" (class so.xmllist.XmlElementsTestBasic$Foo), not marked as ignorable (one known property: "items"])
at [Source: (StringReader); line: 2, column: 15] (through reference chain: so.xmllist.XmlElementsTestBasic$Foo["A"])

关于java - 使用 Jackson 反序列化 XML 以从 XSD 生成选择时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50787107/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com