【问题标题】:how to skip xml elements while loading into pojo (in xstream/jaxb)如何在加载到 pojo 时跳过 xml 元素(在 xstream/jaxb 中)
【发布时间】:2015-12-07 17:03:55
【问题描述】:

我有一个非常大且复杂的 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

   }

问题是如何在将 xml 元素加载到 pojo 时跳过它?

【问题讨论】:

    标签: java xml xml-parsing jaxb xstream


    【解决方案1】:

    您可以使用Jackson XML librairy 完成此操作。 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>
    

    还有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()

    公共类 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]

    【讨论】:

    • 但无论如何,您将内容字段的价值设为 EMPTY,并且您还创建了类似于 xml 的 pojo 结构。我只想在我的 pojo 中有必需的 xml 字段。我不想在 pojo 中不必要地声明字段..
    • 你还没有理解最后一部分:你可以拥有一个只有你想要的属性的pojo。为此,您需要将DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES 设置为false。事实上,EMPTY 只是我在toString() 方法中输入的String。请参阅编辑以获取您确切想要的示例。
    • 假设在您的示例中,作者元素具有子元素,例如 id、姓名、地址、书籍列表等。那么我可以直接使用 @JacksonXmlProperty 获取作者姓名,而无需将 Author 作为单独的 pojo 吗?
    • 您必须定义一个单独的 pojo Author,并带有属性 name。通过指定元素的路径来展平 xml 树可能会很有趣。可能是 JacksonXML 进化的一些建议......
    猜你喜欢
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多