如何在加载到 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 的完整示例:

假设我们有一个只有 idtitle 的 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]