JAVA - 使用 FasterXml.Jackson 将 XML 文件解析为 Map

Posted

技术标签:

【中文标题】JAVA - 使用 FasterXml.Jackson 将 XML 文件解析为 Map【英文标题】:JAVA - Parsing an XML file into Map using FasterXml.Jackson 【发布时间】:2017-12-17 22:07:48 【问题描述】:

我有以下 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<Site xmlns="bla" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  id="0" affiliations="foo" status="OPERATIONAL" color="#DB2253" updateTime="2002-12-17T09:30:47.0Z" name="GFB_0035" subject="GF">
    <location>
        <vertices Lat="41.905889" Lon="12.452019"/>
        <vertices Lat="41.905973" Lon="12.453596"/>
        <vertices Lat="41.905206" Lon="12.453707"/>
        <vertices Lat="41.905058" Lon="12.452109"/>
    </location>
</Site>

我正在使用FasterXml.Jackson 将数据解析为Map&lt;String, Object&gt; 对象使用以下代码:

XmlMapper xmlMapper = new XmlMapper();
Map<String, Object> data = xmlMapper.readValue(new File(xmlFile), Map.class);

但是,当我查看 "location" 字段的内容时,我只有一个顶点而不是四个(最后一个)。

更新: 我得到的地图对象如下所示:

id=0, affiliations=foo, status=OPERATIONAL, color=#DB2253, updateTime=2002-12-17T09:30:47.0Z, name=GFB_0035, subject=GF, location=vertices=Lat=41.905058, Lon=12.452109

有没有办法使用FasterXml.Jackson 获取所有四个条目?

【问题讨论】:

你的输出是什么样子的? 我已经用我的代码输出更新了问题 【参考方案1】:

根据Java Documentation-

地图不能包含重复的键;每个键最多可以映射到一个值。

这就是为什么当您查看“位置”字段的内容时,您只有一个顶点而不是四个(最后一个)。

我认为您应该在自己的类中解析 XML,而不是将其存储到 Map

见下面的例子-

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;

public class Stack 


    public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException 

        String xmlFile = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<Site xmlns=\"bla\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"  id=\"0\" affiliations=\"foo\""
                + " status=\"OPERATIONAL\" color=\"#DB2253\" updateTime=\"2002-12-17T09:30:47.0Z\" name=\"GFB_0035\" "
                + "subject=\"GF\">"
                + "    <location>"
                + "        <vertices lat=\"41.905889\" lon=\"12.452019\"/>"
                + "        <vertices lat=\"41.905973\" lon=\"12.453596\"/>"
                + "        <vertices lat=\"41.905206\" lon=\"12.453707\"/>"
                + "        <vertices lat=\"41.905058\" lon=\"12.452109\"/>"
                + "    </location>"
                + "</Site>";

        XmlMapper mapper = new XmlMapper();
        SiteData site = mapper.readValue(xmlFile, SiteData.class);
        System.out.println(site);
    


SiteData.java

import com.fasterxml.jackson.xml.annotate.JacksonXmlProperty;
import com.fasterxml.jackson.xml.annotate.JacksonXmlRootElement;

@JacksonXmlRootElement(localName = "Site")
public class SiteData 

    private String id;

    private String affiliations;

    private String status;

    private String color;

    private String updateTime;

    private String name;

    private String subject;

    @JacksonXmlProperty(localName = "location")
    private LocationData location;

    public String getId() 
        return id;
    

    public void setIdValue(String id) 
        this.id = id;
    

    public String getAffiliations() 
        return affiliations;
    

    public void setAffiliations(String affiliations) 
        this.affiliations = affiliations;
    

    public String getStatus() 
        return status;
    

    public void setStatus(String status) 
        this.status = status;
    

    public String getColor() 
        return color;
    

    public void setColor(String color) 
        this.color = color;
    

    public String getUpdateTime() 
        return updateTime;
    

    public void setUpdateTime(String updateTime) 
        this.updateTime = updateTime;
    

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getSubject() 
        return subject;
    

    public void setSubject(String subject) 
        this.subject = subject;
    

    public LocationData getLocation() 
        return location;
    

    public void setLocation(LocationData location) 
        this.location = location;
    

    @Override
    public String toString() 
        return "Site [id=" + id + ", affiliations=" + affiliations
                + ", status=" + status + ", color=" + color + ", updateTime="
                + updateTime + ", name=" + name + ", subject=" + subject
                + ", locations=" + location + "]";
    

LocationData.java

import java.util.List;

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;

public class LocationData 

    @JacksonXmlElementWrapper(useWrapping=false)
    private List<VerticesData> vertices;

    public List<VerticesData> getVertices() 
        return vertices;
    

    public void setVertices(List<VerticesData> vertices) 
        this.vertices = vertices;
    

    @Override
    public String toString() 
        return "LocationData [vertices=" + vertices + "]";
    


VerticesData.java

public class VerticesData 

    private String lat;

    private String lon;

    public String getLat() 
        return lat;
    

    public void setLat(String lat) 
        this.lat = lat;
    

    public String getLon() 
        return lon;
    

    public void setLon(String lon) 
        this.lon = lon;
    

    @Override
    public String toString() 
        return "Vertices [lat=" + lat + ", lon=" + lon + "]";
    


输出:

Site [id=0, affiliations=foo, status=OPERATIONAL, color=#DB2253, updateTime=2002-12-17T09:30:47.0Z, name=GFB_0035, subject=GF, locations=LocationData [vertices=[Vertices [lat=41.905889, lon=12.452019], Vertices [lat=41.905973, lon=12.453596], Vertices [lat=41.905206, lon=12.453707], Vertices [lat=41.905058, lon=12.452109]]]]

【讨论】:

该位置是否可以包含顶点列表? 是的,我建议您编写自定义类并将 XML 解析为该类。 @ZachiShtain 查看更新的答案,我添加了示例。

以上是关于JAVA - 使用 FasterXml.Jackson 将 XML 文件解析为 Map的主要内容,如果未能解决你的问题,请参考以下文章

@JsonInclude(Include.NON_NULL)

@JsonInclude(Include.NON_NULL)

java-uf命令使用

Java类文件格式主要版本号列表?

使用Java代码和注解完成Spring配置

我应该采用 Java 12 还是坚持使用 Java 11?