使用JAXB解组具有不同/动态名称的元素

时间:2009-05-07 14:43:22

标签: java xml serialization orm jaxb

我正在解析一个包含如下节点的XML文档:

<objects>
  <dog>
    <data1>...</data1>
    <data2>...</data2>
    <data3>...</data3>
  </dog>
  <cat>
    <data1>...</data1>
    <data2>...</data2>
    <data3>...</data3>
  </cat>
</objects>

元素data1,data2,data3始终保持一致。只有父标签有所不同。在我的对象模型中,我有一个Object,它代表所有这些情况。如何在不事先知道元素名称的情况下让JAXB处理这种情况?

@XMLAnyElement匹配所有对象,但不创建适当类型的对象;我得到一个Node对象列表而不是我的对象。我的对象目前看起来像:

public class MyObject {
    protected String otherData;

    @XmlAnyElement
    @XmlElementWrapper(name = "objects")
    protected List<MyChildObject> childObjects;
}

public class MyChildObject {
    protected String data1;
    protected String data2;
    protected String data3;
}

如何处理这种情况的任何想法都不会改变传入的XML格式以使用<object type="dog">元素?

2 个答案:

答案 0 :(得分:7)

如果名称真的是动态的,那么我认为JAXB不会帮助你。如果您有各种元素名称的定义数量,那么您可以像建议的其他帖子一样使用继承。如果元素和名称的数量未知,我建议使用这样的东西:

@XmlMixed
@XmlAnyElement
public List<Object> getObjects() {
    return objects;
}

这会使元素只是一个DOM元素。然后,您可以再次使用JAXB将每个元素转换为自定义类型。

如果您必须使用JAXB,那就是这样。您可能会发现直接将SAX或DOM API用于此类数据会更容易。 JAXB实际上适用于可以表示为模式的定义良好的数据。

答案 1 :(得分:0)

您可以使用继承:

@XmlRootElement(name = "dog")
public class MyDogObject extends MyChildObject {
    //nothing here
}

@XmlRootElement(name = "cat")
public class MyCatObject extends MyChildObject {
    //nothing here
}

这样,它可以让您处理相同的对象类型MyChildObject,同时灵活地控制XML结构。另一个好处是,如果您将来定义特定的狗/猫XML节点 - 它们可以按照预期映射到相应的子类而不映射到另一个子节点。