我必须转换xml
至Map<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 个字段的实例:Name
和URIPath
。如果您愿意,您可以稍后从集合中构建 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/