Java JAXB将XML元素解组到HashMap

Java JAXB将XML元素解组到HashMap,java,xml,jaxb,hashmap,Java,Xml,Jaxb,Hashmap,我发现很多文章描述了如何将XML元素序列解组到HashMap,只要它们位于“父”元素中。但是,我不能直接在根元素下处理这些子元素 方案1-工程: <?xml version="1.0" encoding="UTF-8"?> <checks> <checks> <check key="check1"/> <check key="check2"/> ... </checks> <

我发现很多文章描述了如何将XML元素序列解组到HashMap,只要它们位于“父”元素中。但是,我不能直接在根元素下处理这些子元素

方案1-工程:

<?xml version="1.0" encoding="UTF-8"?>
<checks>
  <checks>
    <check key="check1"/>
    <check key="check2"/>
    ...       
  </checks>
</checks>
检查映射类型:

package com.foo.conf;
导入java.util.List;
导入javax.xml.bind.annotation.xmlement;
类CheckMapType{
@xmlement(name=“check”)
公共列表清单;/=新的ArrayList();
}
检查适配器:

package com.foo.conf;
导入java.util.HashMap;
导入java.util.Map;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
最后一个类ChecksAdapter扩展了XmlAdapter{
@凌驾
公共CheckMapType封送处理程序(映射arg0)引发异常{
返回null;
}
@凌驾
公共映射解组器(CheckMapType arg0)引发异常{
System.out.println(“u:+arg0.checkList.size());
Map Map=newhashmap();
用于(检查:arg0.检查表){
系统输出打印项次(检查);
地图放置(check.key,check);
}
返回图;
}       
}
这是(一些虚拟测试行)生成类/调用解组的方式:

JAXBContext jc=JAXBContext.newInstance(Checks.class);
解组器u=jc.createUnmarshaller();
Checks c=(Checks)u.unmarshal(新文件(“Checks.xml”);
System.out.println(c.checkMap.size());
你知道如何让选项2发挥作用吗?它在使用列表而不是映射时工作,但我需要HashMap,因为我必须通过给定的键访问对象


非常感谢任何提示

如何生成JAXB类?我不知道你到底想做什么,但下面的代码对我来说非常简单

    JAXBContext jc = JAXBContext.newInstance(ChecksType.class);

    Unmarshaller unmarshaller = jc.createUnmarshaller();
    ChecksType chksType = (ChecksType) unmarshaller.unmarshal(new File("/path/to/xml"));

    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(chksType, System.out);

    System.err.println(chksType.getCheck().get(0).getKey());

    for (CheckType checkType : chksType.getCheck()) {
        System.out.println("key = " + checkType.getKey() + ", " + checkType);
    }
这是我的JAXB生成的类。。
ChecksType
(根元素)


注意:我是专家组的负责人和成员

JAXB将用嵌套关系处理每个对象关系<代码>映射被视为一个
对象
而不是
集合
,因此这就是您获得所看到的行为的原因

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;     
}
package com.foo.conf;
导入java.util.Map;
导入javax.xml.bind.annotation.xmlement;
导入javax.xml.bind.annotation.XmlRootElement;
导入javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
导入org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name=“checks”)
公共类检查{
@XmlJavaTypeAdapter(ChecksAdapter.class)
@XmlPath(“.”)
公共地图检查图;
}
了解更多信息


感谢您的评论。但是它并没有回答实际的问题,正如我提到的,它使用ArrayList工作,但不使用HashMap-这就是我需要的。感谢非常有用的解释-我将很快尝试一下。
   @XmlAccessorType(XmlAccessType.FIELD)
   @XmlType(name = "checksType", propOrder = { "check" })
   @XmlRootElement(name = "checks")
   public class ChecksType {

         @XmlElement(required = true)
         protected List<CheckType> check;


        public List<CheckType> getCheck() {
           if (check == null) {
             check = new ArrayList<CheckType>();
           }
           return this.check;
        }

   }
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "checkType")
    public class CheckType {

         @XmlAttribute(name = "key")
         protected String key;


         public String getKey() {
            return key;
         }


         public void setKey(String value) {
            this.key = value;
         }

   }
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;     
}