JAXB 将 XML 元素解组到 HashMap

2024-04-22

我发现很多文章描述了如何将 XML 元素序列解组到 HashMap(只要它们位于“父”元素内)。但是,我无法将此与直接在根元素下的子元素一起使用!

选项 1 - 有效:

<?xml version="1.0" encoding="UTF-8"?>
<checks>
  <checks>
    <check key="check1"/>
    <check key="check2"/>
    ...       
  </checks>
</checks>

选项 2 - 是否not work:

<?xml version="1.0" encoding="UTF-8"?>
<checks>
  <check key="check1"/>
  <check key="check2"/>
  ...
</checks>

Checks:

package com.foo.conf;

import java.util.Map;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name="checks")
public class Checks {       
    @XmlJavaTypeAdapter(ChecksAdapter.class)
    @XmlElement(name="checks")
    public Map<String, Check> checkMap;     
}

Check:

package com.foo.conf;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;

public class Check {
    @XmlAttribute public String key;
    @XmlValue public String description;

    public Check() { }

    public Check(String key) {
        this.key = key;
    }

    public String getCheckKey() {
        return this.key;
    }
}

检查地图类型:

package com.foo.conf;

import java.util.List;

import javax.xml.bind.annotation.XmlElement;

class CheckMapType { 
    @XmlElement(name="check")
    public List<Check> checkList; // = new ArrayList<Check>();
}

检查适配器:

package com.foo.conf;

import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.annotation.adapters.XmlAdapter;

final class ChecksAdapter extends XmlAdapter<CheckMapType, Map<String, Check>> {

    @Override
    public CheckMapType marshal(Map<String, Check> arg0) throws Exception {
        return null;
    }

    @Override
    public Map<String, Check> unmarshal(CheckMapType arg0) throws Exception {
        System.out.println("u: " + arg0.checkList.size());
        Map<String, Check> map = new HashMap<String, Check>();

        for (Check check : arg0.checkList) {
            System.out.println(check);
            map.put(check.key, check);
        }
        return map;
    }       
}

这是(一些虚拟测试行)我生成类/调用解组的方式:

JAXBContext jc = JAXBContext.newInstance(Checks.class);
Unmarshaller u = jc.createUnmarshaller();
Checks c = (Checks) u.unmarshal(new File("checks.xml"));
System.out.println(c.checkMap.size());

知道如何让选项 #2 发挥作用吗?它在使用列表而不是映射时有效,但我需要 HashMap,因为我必须通过给定的键访问对象......

任何提示非常感谢!


Note:我是EclipseLink JAXB (MOXy) http://www.eclipse.org/eclipselink/moxy.php领导者和成员JAXB (JSR-222) https://jcp.org/en/jsr/detail?id=222专家组。

JAXB 将用嵌套关系来对待每个对象关系。Map被视为Object代替Collection所以这就是为什么你会出现你所看到的行为。

MOXy 有一个基于 XPath 的映射扩展,称为@XmlPath可以用于此用例。

package com.foo.conf;

import java.util.Map;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@XmlRootElement(name="checks")
public class Checks {       
    @XmlJavaTypeAdapter(ChecksAdapter.class)
    @XmlPath(".")
    public Map<String, Check> checkMap;     
}

了解更多信息

  • http://blog.bdoughan.com/2010/07/xpath-based-mapping.html http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
  • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAXB 将 XML 元素解组到 HashMap 的相关文章

随机推荐