java - 如何在杰克逊中取消多个嵌套元素?
问题描述
我需要构建一个解析器来将XML
文件解析为Java
对象。我曾经Jackson
这样做并遵循本教程中提供的步骤。
教程中有一节“在 XML 中操作嵌套元素和列表”。我跟着它,但不幸的是,我无法获得所有所需元素的所需输出 - 我想输出我所有作者的第一个和最后一个。我只在文件中为我的最后一位作者得到它,XML
如下所示:
[{nameList={person={first=Karl, last=S}}}]
我的XML
文件看起来像这样。
<sources>
<Doi>123456789</Doi>
<Title>Title</Title>
<author>
<editor>
<nameList>
<person>
<first>Peter</first>
<last>Parker</last>
</person>
</nameList>
</editor>
</author>
<Source>
<SourceType>Book</SourceType>
<ShortTitle>Book Title</ShortTitle>
<Author>
<Editor>
<NameList />
</Editor>
</Author>
</Source>
<author>
<bookAuthor>
<nameList>
<person>
<first>Karl</first>
<last>S</last>
</person>
</nameList>
</bookAuthor>
</author>
<Source>
<SourceType>Journal</SourceType>
<ShortTitle>ABC Journal</ShortTitle>
</Source>
</sources>
如何取消实现整个 XML 文件?
我的代码如下所示:MyClass.java
private static void jacksonXmlFileToObject() throws IOException {
System.out.println("jacksonXmlFileToObject");
InputStream xmlFile = Publication.class.getClassLoader().getResourceAsStream("test.xml");
ObjectMapper mapper = new XmlMapper();
// Configure
mapper
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try {
Sources deserializedData = mapper.readValue(xmlFile, Sources.class);
System.out.println(deserializedData);
} catch (IOException e) {
e.printStackTrace();
}
}
来源.java
@EqualsAndHashCode
@JacksonXmlRootElement(localName = "sources") public class Sources {
@JacksonXmlElementWrapper(localName = "author")
@Getter
@Setter
private Object[] author;
@Override
public String toString() {
return Arrays.toString(author);
}
public Sources() {
}
}
我会很高兴得到一些帮助。
谢谢!
解决方案
使用JsonMerge
注释。
我最近自己也遇到了类似的问题,发现注释@JsonMerge
解决了这个问题。
我稍微简化了 XML:
<sources>
<author>
<name>Jack</name>
</author>
<source>
<type>Book</type>
</source>
<author>
<name>Jill</name>
</author>
<source>
<type>Journal</type>
</source>
</sources>
随着班级Author
和Source
class Author {
String name;
}
class Source {
String type;
}
该类Sources
如下所示:
class Sources {
// We prevent each <author> tag to be wrapped in an <authors> container tag
@JacksonXmlElementWrapper(useWrapping = false)
// Each element is <author> and not <authors> (and we named our field 'authors')
@JacksonXmlProperty(localName = "author")
// This is the property which solves your problem. It causes non-subsequent elements with the
// same name to be merged into the existing list
@JsonMerge
private List<Author> authors;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "source")
@JsonMerge
private List<Source> sources;
}