Java 如何在加载到pojo时跳过xml元素(在xstream/jaxb中)
我有一个非常大且复杂的xml,我只想将选定的字段加载到我的对象中。 我尝试过xstream,但我理解的是我的xml结构必须与我的pojo相似。 我提供样品I/p和o/p,以便更好地理解Java 如何在加载到pojo时跳过xml元素(在xstream/jaxb中),java,xml,xml-parsing,jaxb,xstream,Java,Xml,Xml Parsing,Jaxb,Xstream,我有一个非常大且复杂的xml,我只想将选定的字段加载到我的对象中。 我尝试过xstream,但我理解的是我的xml结构必须与我的pojo相似。 我提供样品I/p和o/p,以便更好地理解 <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</bo
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
问题是如何在将xml元素加载到pojo时跳过它?您可以使用它。Jackson可能更出名的是JSON
序列化/反序列化,但它有一个XML扩展
如果您的XML文件很大,请查看上面的链接,了解如何部分/增量地读取它以获得最佳性能
下面是一个示例,说明如何在不希望反序列化的字段上使用@JsonIgnore
注释,仅读取属性的子集:
@JacksonXmlRootElement(localName = "jokes")
class Jokes {
@JacksonXmlProperty(localName = "joke")
@JacksonXmlElementWrapper(useWrapping = false)
private Joke[] jokes;
// getter, setter omitted
}
class Joke {
@JacksonXmlProperty(isAttribute = true)
long id;
@JacksonXmlProperty(localName = "title")
String title;
@JsonIgnore
String author;
@JacksonXmlProperty(localName = "like")
long like;
@JsonIgnore
String content;
public String toString() {
return Arrays.stream(new Object[] {id, title, author, like, content})
.map(o -> o!=null ? o.toString() : "EMPTY")
.collect(Collectors.joining(", ", "[", "]"));
}
// getters, setters omitted
}
使用示例文件:
<jokes>
<joke id="123">
<title>C'est l'histoire d'un mec</title>
<author>Coluche</author>
<content>Blah blah blah</content>
<like>4509</like>
</joke>
<joke id="777">
<title>Si j'ai bien tout lu freud</title>
<author>Coluche</author>
<content>Blah blah blah</content>
<like>345</like>
</joke>
</jokes>
输出为(注意空字段):
[123,C'est l'historire d'un mec,EMPTY,4509,EMPTY][777,Si j'ai bien tout lu freud,空,345,空] 您还可以创建一个只包含所需字段的pojo,然后不使用
@JsonIgnore
。为此,必须通知XmlMapper
忽略未知的XML属性
XmlMapper mapper = new XmlMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
编辑 您希望pojo只包含几个字段的完整示例如下: 假设我们有一个只有
id
和title
的pojo:
class Joke {
@JacksonXmlProperty(isAttribute = true)
long id;
@JacksonXmlProperty(localName = "title")
String title;
public String toString() {
return new StringBuffer().append('[')
.append(id).append(',')
.append(title).append(']').toString();
}
// getters setters
}
使用上述xml文件执行以下main()
:
公共类XmlJokerReader{
public static void main(String[] args) throws JsonProcessingException, IOException {
XmlMapper mapper = new XmlMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Jokes jokesDoc = mapper.readValue(new File("./data/jokes.xml"), Jokes.class);
for (Joke joke : jokesDoc.getJokes()) {
System.out.println(joke.toString());
}
}
}
将提供:
[123,C'est l'historire d'un mec][777,Si j'ai bien tout lu freud] 您可以使用.Jackson进行序列化/反序列化,它可能以
JSON
序列化/反序列化而闻名,但它有一个XML扩展
如果您的XML文件很大,请查看上面的链接,了解如何部分/增量地读取它以获得最佳性能
下面是一个示例,说明如何在不希望反序列化的字段上使用@JsonIgnore
注释,仅读取属性的子集:
@JacksonXmlRootElement(localName = "jokes")
class Jokes {
@JacksonXmlProperty(localName = "joke")
@JacksonXmlElementWrapper(useWrapping = false)
private Joke[] jokes;
// getter, setter omitted
}
class Joke {
@JacksonXmlProperty(isAttribute = true)
long id;
@JacksonXmlProperty(localName = "title")
String title;
@JsonIgnore
String author;
@JacksonXmlProperty(localName = "like")
long like;
@JsonIgnore
String content;
public String toString() {
return Arrays.stream(new Object[] {id, title, author, like, content})
.map(o -> o!=null ? o.toString() : "EMPTY")
.collect(Collectors.joining(", ", "[", "]"));
}
// getters, setters omitted
}
使用示例文件:
<jokes>
<joke id="123">
<title>C'est l'histoire d'un mec</title>
<author>Coluche</author>
<content>Blah blah blah</content>
<like>4509</like>
</joke>
<joke id="777">
<title>Si j'ai bien tout lu freud</title>
<author>Coluche</author>
<content>Blah blah blah</content>
<like>345</like>
</joke>
</jokes>
输出为(注意空字段):
[123,C'est l'historire d'un mec,EMPTY,4509,EMPTY][777,Si j'ai bien tout lu freud,空,345,空] 您还可以创建一个只包含所需字段的pojo,然后不使用
@JsonIgnore
。为此,必须通知XmlMapper
忽略未知的XML属性
XmlMapper mapper = new XmlMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
编辑 您希望pojo只包含几个字段的完整示例如下: 假设我们有一个只有
id
和title
的pojo:
class Joke {
@JacksonXmlProperty(isAttribute = true)
long id;
@JacksonXmlProperty(localName = "title")
String title;
public String toString() {
return new StringBuffer().append('[')
.append(id).append(',')
.append(title).append(']').toString();
}
// getters setters
}
使用上述xml文件执行以下main()
:
公共类XmlJokerReader{
public static void main(String[] args) throws JsonProcessingException, IOException {
XmlMapper mapper = new XmlMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Jokes jokesDoc = mapper.readValue(new File("./data/jokes.xml"), Jokes.class);
for (Joke joke : jokesDoc.getJokes()) {
System.out.println(joke.toString());
}
}
}
将提供:
[123,C'est l'historire d'un mec][777,Si j'ai bien tout lu freud]
但无论如何,您得到的内容字段值为空,并且您已经创建了类似于xml的pojo结构。我希望pojo中只包含必需的xml字段。我不希望在pojo中不必要地声明字段。您还没有理解最后一部分:您可以拥有一个pojo,其中只包含您想要的属性。为此,您需要设置
DeserializationFeature.UNKNOWN属性上的失败
到false
。事实上,EMPTY
只是我放入toString()中的字符串
方法。请参见编辑以获取您确切需要的示例。假设在您的示例中,author元素有子元素,如id、name、address、图书列表等。因此,我可以使用@JacksonXmlProperty直接获取author name,而无需将author作为单独的pojo?您必须使用propert定义单独的pojoauthor
yname
。有可能通过指定元素的路径来展平xml树,这可能很有趣。这可能是JacksonXML发展的一些建议……但无论如何,您得到的内容字段值为空,并且您创建了类似于xml的pojo结构。我希望在我的p中只包含必需的xml字段ojo.我不想在pojo中不必要地声明字段..你还没有理解最后一部分:你可以拥有一个只包含你想要的属性的pojo。为此,你需要设置反序列化功能。将未知属性
的失败设置为false
。事实上,空的
只是我放在<代码>toString()
方法。请参见编辑以获取您确切需要的示例。假设在您的示例中,author元素有子元素,如id、name、address、图书列表等。因此,我可以使用@JacksonXmlProperty直接获取author name,而无需将author作为单独的pojo?您必须使用propert定义单独的pojoauthor
yname
。可以通过指定元素的路径来展平xml树,这可能很有趣。这可能是JacksonXML发展的一些建议。。。