Jackson xml反序列化 - 序列化为一个列表,其中包含任意元素
Posted
技术标签:
【中文标题】Jackson xml反序列化 - 序列化为一个列表,其中包含任意元素【英文标题】:Jackson xml deserialization - serialize to a list with arbitrary elements in between 【发布时间】:2020-11-14 19:26:51 【问题描述】:我正在使用 Jackson 来反序列化 XML。当中间没有其他元素时,它在序列化到列表中时工作正常,但是如果我在中间的某个地方插入一些其他字段,它似乎只会将字段下方的内容放入我的列表中。请参见下面仅包含 Product B 标记之后的 ProductA 对象。
我使用xmlMapper readTree方法设置断点获取JsonNode对象,而ProductB标签上面的属性在节点树中是没有的。
有没有办法使用 jackson(或其他库)来获取 Warehouse 元素中的所有 ProductA 元素,而与 Warehouse 子元素的顺序无关?
public class Warehouse
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "ProductA")
private List<ProductA> productAList;
@JacksonXmlProperty(localName = "ProductB")
private String productB;
//getters and setters
public class ProductA
@JacksonXmlProperty(localName = "PropA")
private String propA;
//getters and setters
<Warehouse>
<ProductA>
<propA>abc</propA>
</ProductA>
<ProductA>
<propA>abc</propA>
</ProductA>
<ProductB>def</ProductB>
<ProductA>
<propA>abc</propA>
</ProductA>
</Warehouse>
【问题讨论】:
【参考方案1】:更改您的 Warehouse 类以使用仅用于从 XML 设置 productAList 值的方法,并从 productAList 属性中删除注释。
@JsonSetter(value = "ProductA")
public void setProductAListFromXml(ProductA productA)
if (this.productAList == null)
this.productAList = new ArrayList<ProductA>();
this.productAList.add(productA);
这是完整的 Warehouse 类:
@JacksonXmlRootElement(localName = "Warehouse")
public class Warehouse
private List<ProductA> productAList;
@JacksonXmlProperty(localName = "ProductB")
private String productB;
public List<ProductA> getProductAList()
return productAList;
public void setProductAList(List<ProductA> productAList)
this.productAList = productAList;
@JsonSetter(value = "ProductA")
public void setProductAListFromXml(ProductA productA)
if (this.productAList == null)
this.productAList = new ArrayList<ProductA>();
this.productAList.add(productA);
public String getProductB()
return productB;
public List<ProductA> getProductA()
return productAList;
像这样使用类:
String str = "<Warehouse>\r\n" +
" <ProductA>\r\n" +
" <propA>abc</propA>\r\n" +
" </ProductA>\r\n" +
" <ProductA>\r\n" +
" <propA>abc</propA>\r\n" +
" </ProductA>\r\n" +
" <ProductB>def</ProductB>\r\n" +
" <ProductA>\r\n" +
" <propA>abc</propA>\r\n" +
" </ProductA>\r\n" +
"</Warehouse>";
XmlMapper mapper = new XmlMapper();
Warehouse warehouse = mapper.readValue(str, Warehouse.class);
System.out.println(warehouse.getProductB());
System.out.println(warehouse.getProductA());
产生这个输出:
def
[ProductA [propA=abc], ProductA [propA=abc], ProductA [propA=abc]]
【讨论】:
这适用于其中一个领域,但奇怪的是不适用于另一个领域。假设我有 productC,它与 productA 除了名称之外的所有内容都相同,作为仓库类的一个字段。它正在反序列化所有 productA 元素,但仅反序列化 2 个 productC 中的 1 个。无论如何,我能够使用 w3c/javax 文档解析获得所需的内容。以上是关于Jackson xml反序列化 - 序列化为一个列表,其中包含任意元素的主要内容,如果未能解决你的问题,请参考以下文章