How to unmarshall repeated nested classes with JAXB?

前端 未结 4 1906
故里飘歌
故里飘歌 2020-12-31 11:33

How can I instruct JAXB to process this ?

XML


 
    
          


        
4条回答
  •  谎友^
    谎友^ (楼主)
    2020-12-31 12:12

    You could change your model and do the following:

    Root

    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Root {
       @XmlElement(name="parent")
       List allParents;
    }
    

    Parent

    @XmlAccessorType(XmlAccessType.FIELD)
    public class Parent {
       @XmlElement(name="child")
       List allChildren;
    }
    

    UPDATE

    Is it possible to avoid the parent class ?

    There are a couple of different ways to accomplish this:

    OPTION #1 - Any JAXB Implementation using XmlAdapter

    You could use an XmlAdapter to virtually add in the Parent class.

    ChildAdapter

    import javax.xml.bind.annotation.adapters.XmlAdapter;
    
    public class ChildAdapter extends XmlAdapter {
    
        public static class Parent {
            public Child child;
        }
    
        @Override
        public Parent marshal(Child v) throws Exception {
            Parent parent = new Parent();
            parent.child = v;
            return parent;
        }
    
        @Override
        public Child unmarshal(Parent v) throws Exception {
            return v.child;
        }
    
    }
    

    Root

    The @XmlJavaTypeAdapter annotation is used to reference the XmlAdapter.

    import java.util.List;
    import javax.xml.bind.annotation.*;
    import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Root {
    
       @XmlElement(name="parent")
       @XmlJavaTypeAdapter(ChildAdapter.class)
       List allChildren;
    
    }
    

    Child

    import javax.xml.bind.annotation.*;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Child {
    
        @XmlAttribute
        int id;
    
        @XmlAttribute
        String name;
    
    }
    

    OPTION #2 - Using EclipseLink JAXB (MOXy)

    If you are using EclipseLink JAXB (MOXy) as your JAXB (JSR-222) implementation then you could do the following (Note: I'm the MOXy lead):

    Root

    import java.util.List;
    import javax.xml.bind.annotation.*;
    
    @XmlRootElement
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Root {
    
       @XmlElement(name="parent")
       List allChildren;
    
    }
    

    Child

    MOXy's @XmlPath annotation works pretty much the way you are trying to use the @XmlElement annotation in your post.

    import javax.xml.bind.annotation.*;
    import org.eclipse.persistence.oxm.annotations.XmlPath;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Child {
    
        @XmlPath("child/@id")
        int id;
    
        @XmlPath("child/@name")
        String name;
    
    }
    

    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

提交回复
热议问题