使用属性和未包装的集合反序列化 XML 响应

Posted

技术标签:

【中文标题】使用属性和未包装的集合反序列化 XML 响应【英文标题】:Deserialise XML response with attributes and not wrapped collections 【发布时间】:2020-04-03 00:10:24 【问题描述】:

我正在尝试反序列化来自我的RestTemplateXML 响应,并且该响应包含我需要在映射对象中设置的属性。响应类似于:

<schoolResponse>
    <class id="1" num_of_students="22" name="Ms Barry" >
        <student key="202" value="Jim" />
        <student key="203" value="Tom" />
        <student key="204" value="Dave" />
        <schoolYear>1980</schoolYear>
    </class>
    <class id="2" num_of_students="20" name="Mr Smith">
        <student key="302" value="Jim" />
        <student key="303" value="Tom" />
        <student key="304" value="Dave" />
        <schoolYear>1980</schoolYear>
    </class>
    <class>
        ...
    </class>
</schoolResponse>

我的POJO 是:

@Data
@NoArgsConstructor
public class SchoolResponse 

    @JacksonXmlElementWrapper(localName = "class")
    private List<ClassRoomResponse> classes;




@Data
@NoArgsConstructor
@XmlRootElement(name="class")
public class ClassRoomResponse 

    @XmlAttribute(name = "id")
    private String id;

    @XmlAttribute(name = "num_of_students")
    private String numOfStudents;

    @XmlAttribute(name = "name")
    private String teacherName;

    @XmlElement(name = "schoolYear")
    private String schoolYear;

    @JacksonXmlElementWrapper(localName = "key")
    String key;

    @JacksonXmlElementWrapper(localName = "value")
    String value;

    public ClassRoomResponse(String stringSetter) 

这个映射没有正确设置值,所以,我想知道我在使用这些属性时遇到了什么问题。

【问题讨论】:

以下答案有用吗? 【参考方案1】:

对于Student 节点,您需要一个额外的POJO。此外,您所有的收藏品都已打开。如果您混合使用JAXBJackson 注释,您需要注册com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule 模块。请参阅下面带有固定 POJO 类的示例:

import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class XmlMapperApp 

    public static void main(String... args) throws IOException 
        File xmlFile = new File("./resource/test.xml").getAbsoluteFile();

        XmlMapper xmlMapper = XmlMapper.xmlBuilder()
                .addModule(new JaxbAnnotationModule())
                .build();

        System.out.println(xmlMapper.readValue(xmlFile, SchoolResponse.class));
    


@Data
@NoArgsConstructor
@ToString
class SchoolResponse 

    @XmlElement(name = "class")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<ClassRoomResponse> classes;



@Data
@NoArgsConstructor
class ClassRoomResponse 

    @XmlAttribute(name = "id")
    private String id;

    @XmlAttribute(name = "num_of_students")
    private String numOfStudents;

    @XmlAttribute(name = "name")
    private String teacherName;

    @XmlElement(name = "schoolYear")
    private String schoolYear;

    @XmlElement(name = "student")
    @JacksonXmlElementWrapper(useWrapping = false)
    private List<Student> students;


@Data
@NoArgsConstructor
@ToString
class Student 
    @XmlAttribute(name = "key")
    String key;

    @XmlAttribute(name = "value")
    String value;

上面的代码打印:

SchoolResponse(classes=[ClassRoomResponse(id=1, numOfStudents=22, teacherName=Ms Barry, schoolYear=1980, students=[Student(key=202, value=Jim), Student(key=203, value=Tom), Student(key=204, value=Dave)]), ClassRoomResponse(id=2, numOfStudents=20, teacherName=Mr Smith, schoolYear=1981, students=[Student(key=302, value=Jim), Student(key=303, value=Tom), Student(key=304, value=Dave)])])

【讨论】:

以上是关于使用属性和未包装的集合反序列化 XML 响应的主要内容,如果未能解决你的问题,请参考以下文章

如何序列化/反序列化IList集合的类包装器?

System.Text.Json 反序列化来自 API 调用的嵌套对象 - 数据包装在父 JSON 属性中

包装的 json 属性的反序列化

如何将不同类型的子元素反序列化为基类型的列表/集合,这是相应类的属性

如何在c#中使用具有相同名称但不同属性和结构的元素反序列化XML

Jackson 反序列化同名的 xml 字段