如何指示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>
Root.java
@XmlRootElement
public class Root {
@XmlElement(name="parent/child")
List<Child> allChildren;
}
这不起作用... allChildren是空的。
您可以更改模型并执行以下操作:
根
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElement(name="parent")
List<Parent> allParents;
}
亲
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
@XmlElement(name="child")
List<Child> allChildren;
}
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;
}
}
根
该 @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;
}
儿童
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Child {
@XmlAttribute
int id;
@XmlAttribute
String name;
}
选项#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;
}
儿童
莫西的 @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;
}
了解更多信息
您可以更改模型并执行以下操作:
根
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Root {
@XmlElement(name="parent")
List<Parent> allParents;
}
亲
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
@XmlElement(name="child")
List<Child> allChildren;
}
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;
}
}
根
该 @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;
}
儿童
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Child {
@XmlAttribute
int id;
@XmlAttribute
String name;
}
选项#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;
}
儿童
莫西的 @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;
}
了解更多信息
您将不得不创建一个代表该类的类 <parent>
元素,如
@XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
@XmlElement(name="child")
Child child;
}
然后,您可以创建一个类型适配器
public class ParentToChildAdapter extends XmlAdapter<Parent, Child> {
public Parent marshal(Child c) {
Parent p = new Parent();
p.child = child;
return p;
}
public Child unmarshal(Parent p) {
return p.child;
}
}
并在根类上使用它
@XmlRootElement
public class Root {
@XmlElement(name="parent")
@XmlJavaTypeAdapter(ParentToChildAdapter.class)
List<Child> allChildren;
}
你可以尝试使用 XmlElementWrapper
注释但我不确定它应该如何与多个包装器节点一起使用:
@XmlRootElement
public class Root {
@XmlElementWrapper(name="parent")
@XmlElement(name="child")
List<Child> allChildren;
}
尝试这个
@XmlRootElement
class Root {
List<Child> allChildren = new ArrayList<Child>();
private static class Parent {
@XmlElement
Child child;
}
@XmlElement
public void setParent(Parent p) {
allChildren.add(p.child);
}
}