如何在加载到 pojo 时跳过 xml 个元素(在 xstream/jaxb 中)
how to skip xml elements while loading into pojo (in xstream/jaxb)
我有一个非常大且复杂的 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!</body>
</note>
Pojo 将
class Note{
long noteId;
String body;
//getters and setters
}
问题是如何在加载到 pojo 时跳过 xml 个元素?
您可以使用 Jackson XML librairy 来完成。杰克逊可能因 JSON
serialising/deserialising 而更出名,但它有一个 XML 扩展名。
如果您的 XML 文件很大,请查看上面的 link 以了解如何 partially/incrementally 读取它以获得最佳性能。
无论如何,下面是一个示例,说明如何在不希望反序列化的字段上使用 @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>
还有 main()
public class XmlJokeReader {
public static void main(String[] args) throws JsonProcessingException, IOException {
XmlMapper mapper = new XmlMapper();
Jokes jokesDoc = mapper.readValue(new File("./data/jokes.xml"), Jokes.class);
Arrays.stream(jokesDoc.getJokes()).forEach(j -> System.out.println(j.toString()));
}
}
输出是(注意 EMPTY 字段):
[123, C'est l'histoire d'un mec, EMPTY, 4509, EMPTY]
[777, Si j'ai bien tout lu freud, EMPTY, 345, EMPTY]
您还可以创建一个只包含您需要的字段的 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()
:
public class XmlJokeReader {
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'histoire d'un mec]
[777,Si j'ai bien tout lu freud]
我有一个非常大且复杂的 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!</body>
</note>
Pojo 将
class Note{
long noteId;
String body;
//getters and setters
}
问题是如何在加载到 pojo 时跳过 xml 个元素?
您可以使用 Jackson XML librairy 来完成。杰克逊可能因 JSON
serialising/deserialising 而更出名,但它有一个 XML 扩展名。
如果您的 XML 文件很大,请查看上面的 link 以了解如何 partially/incrementally 读取它以获得最佳性能。
无论如何,下面是一个示例,说明如何在不希望反序列化的字段上使用 @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>
还有 main()
public class XmlJokeReader {
public static void main(String[] args) throws JsonProcessingException, IOException {
XmlMapper mapper = new XmlMapper();
Jokes jokesDoc = mapper.readValue(new File("./data/jokes.xml"), Jokes.class);
Arrays.stream(jokesDoc.getJokes()).forEach(j -> System.out.println(j.toString()));
}
}
输出是(注意 EMPTY 字段):
[123, C'est l'histoire d'un mec, EMPTY, 4509, EMPTY]
[777, Si j'ai bien tout lu freud, EMPTY, 345, EMPTY]
您还可以创建一个只包含您需要的字段的 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()
:
public class XmlJokeReader {
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'histoire d'un mec]
[777,Si j'ai bien tout lu freud]