java - 如何使用 JAXB 和 Spring 解码具有重复条目的 xml

标签 java xml spring jaxb

我必须转换xmlMap<String,String> 。我有以下 XML 结构:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Environments>
  <Environment Name="A" URIPath="http://a.com" />
  <Environment Name="B" URIPath="http://b.com" />
  <Environment Name="C" URIPath="http://c.com" />
</Environments> 

我尝试了多种方法,但最终得到了 Class has two properties of the same name "URIPath" 。解码此 XML 的正确设计是什么?

更新:

使用提供的解决方案#1,我得到:

Class has two properties of the same name "environments"
    this problem is related to the following location:
        at public java.util.List app.model.Environments.getEnvironments()
        at app.model.Environments
    this problem is related to the following location:
        at public java.util.List app.model.Environments.environments
        at app.model.Environments
Class has two properties of the same name "URIPath"
    this problem is related to the following location:
        at public java.lang.String app.model.Environment.getURIPath()
        at app.model.Environment
        at public java.util.List app.model.Environments.environments
        at app.model.Environments
    this problem is related to the following location:
        at java.lang.String app.model.Environment.URIPath
        at app.model.Environment
        at public java.util.List app.model.Environments.environments
        at app.model.Environments
] with root cause

最佳答案

您有 2 个选择:

1) 解码 Environment 的集合具有 2 个字段的实例:NameURIPath 。如果您愿意,您可以稍后从集合中构建 map 。

2) 使用自定义 XmlAdapter 它正确地从集合中创建 map 。

详细阐述解决方案 #1

该解决方案需要以下类:

class Environments {
    @XmlElement(name = "Environment")
    public List<Environment> environments;
}

class Environment {
    @XmlAttribute(name = "Name")
    public String Name;
    @XmlAttribute(name = "URIPath")
    public String URIPath;
}

并使用这些,解码:

Environments environments = JAXB.unmarshal(new File("env.xml"),
    Environments.class);

详细阐述解决方案#2

如果您想使用自定义 XmlAdapter直接获取Map ,无法使用当前形式的 XML 输入。必须稍微修改它才能在其周围放置一个包装器 XML 元素。这是必需的,因为在 Java 中 Map是一个类的属性,但是 <Environments>标签只是 Map 的包装器。修改后的 XML 示例:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<wrapper>
  <Environments>
    <Environment Name="A" URIPath="http://a.com" />
    <Environment Name="B" URIPath="http://b.com" />
    <Environment Name="C" URIPath="http://c.com" />
  </Environments>
</wrapper>

以此作为输入 XML,解决方案如下:

class EnvironmentMap {
    @XmlJavaTypeAdapter(value = EnvMapAdapter.class)
    @XmlElement(name = "Environments")
    public Map<String, String> envMap;
}

class Environments {
    @XmlElement(name = "Environment")
    public List<Environment> environments;
}

class Environment {
    @XmlAttribute(name = "Name")
    public String name;
    @XmlAttribute(name = "URIPath")
    public String uriPath;
}

class EnvMapAdapter extends XmlAdapter<Environments, Map<String, String>> {
    @Override
    public Map<String, String> unmarshal(Environments envs) throws Exception {
        Map<String, String> map = new HashMap<>();
        for (Environment env : envs.environments)
            map.put(env.name, env.uriPath);
        return map;
    }

    @Override
    public Environments marshal(Map<String, String> map) throws Exception {
        Environments environments = new Environments();
        // This method is only called if you marshal (Java -> XML)
        environments.environments = new ArrayList<>(map.size());

        for (Entry<String, String> entry : map.entrySet()) {
            Environment e = new Environment();
            e.name = entry.getKey();
            e.uriPath = entry.getValue();
            environments.environments.add(e);
        }

        return environments;
    }
}

并使用它:

EnvironmentMap envMap = JAXB.unmarshal(new File("env2.xml"),
    EnvironmentMap.class);
System.out.println(envMap.envMap);

打印内容:

{A=http://a.com, B=http://b.com, C=http://c.com}

关于java - 如何使用 JAXB 和 Spring 解码具有重复条目的 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26603610/

相关文章:

java - spring data jpa 不必要的左连接

java - 切换按钮与图像更改按钮

java - 根据另一个字段的值有条件地反序列化一个字段

c# - 如何使用 C# 比较两个 XML 文件并添加缺失的元素

java - 您可以为 Spring MVC 中的单个路径指定首选默认媒体类型吗?

javascript - 如何在 Spring 中正确创建 JavaScript 日期数组?

JAVA 8 过滤具有任何匹配属性的对象列表

json - Django RestFramework 分组依据

javascript - jQuery GET 未成功

java - @Transactional 方法中的 Spring 事务处理 JMSTemplate