JAXB unmarshal XML elements to HashMap

前端 未结 2 1734
故里飘歌
故里飘歌 2021-01-21 14:20

I found a lot of articles that describe how to unmarshal a sequence of XML elements to a HashMap as long as they are within a \"parent\" element. However, I do not get this to w

相关标签:
2条回答
  • 2021-01-21 15:06

    Note: I'm the EclipseLink JAXB (MOXy) lead and a member of the JAXB (JSR-222) expert group.

    JAXB will treat each object relationship with a nesting relationship. Map is treated like an Object instead of a Collection so this is why you are getting the behaviour that you are seeing.

    MOXy has an XPath based mapping extension called @XmlPath that could be used for this use case.

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

    For More Information

    • http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
    • http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
    0 讨论(0)
  • 2021-01-21 15:11

    How are you generaing the JAXB classes? I am not sure what exactly are you trying to do but the below very simple code works for me ..

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

    and here is my JAXB generated classes .. ChecksType (Root element)

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

    And checkType (the child)

        @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;
             }
    
       }
    
    0 讨论(0)
提交回复
热议问题