如何使用JAXB解组重复的嵌套类?

Ste*_*han 11 java jaxb

如何指示JAXB处理此问题?

XML

<root>
 <parent>
    <child id="1" name="foo" />
 </parent>
 <parent>
    <child id="3" name="foo2" />
 </parent>
 <parent>
    <child id="4" name="bar2" />
 </parent>
 <parent>
    <child id="2" name="bar" />
 </parent>
</root>
Run Code Online (Sandbox Code Playgroud)

Root.java

@XmlRootElement
public class Root {
   @XmlElement(name="parent/child")
   List<Child> allChildren;
}
Run Code Online (Sandbox Code Playgroud)

这不起作用... allChildren是空的.

bdo*_*han 13

您可以更改模型并执行以下操作:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
   @XmlElement(name="parent")
   List<Parent> allParents;
}
Run Code Online (Sandbox Code Playgroud)

@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
   @XmlElement(name="child")
   List<Child> allChildren;
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

是否可以避免父类?

有几种不同的方法可以实现这一目标:

选项#1 - 使用XmlAdapter的任何JAXB实现

您可以使用XmlAdapter虚拟地添加到Parent类中.

ChildAdapter

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

public class ChildAdapter extends XmlAdapter<ChildAdapter.Parent, Child> {

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

}
Run Code Online (Sandbox Code Playgroud)

@XmlJavaTypeAdapter注释被用于引用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<Child> allChildren;

}
Run Code Online (Sandbox Code Playgroud)

儿童

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Child {

    @XmlAttribute
    int id;

    @XmlAttribute
    String name;

}
Run Code Online (Sandbox Code Playgroud)

选项#2 - 使用EclipseLink JAXB(MOXy)

如果您使用EclipseLink JAXB(MOXy)作为JAXB(JSR-222)实现,那么您可以执行以下操作(注意:我是MOXy主管):

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {

   @XmlElement(name="parent")
   List<Child> allChildren;

}
Run Code Online (Sandbox Code Playgroud)

儿童

MOXy的@XmlPath注释与您尝试@XmlElement在帖子中使用注释的方式非常相似.

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;

}
Run Code Online (Sandbox Code Playgroud)

欲获得更多信息

  • +1当我独立提出与该领域公认的专家完全相同的解决方案时,它总是令人放心:-) (4认同)