是否可以在JAXB编组期间忽略包装类

时间:2012-06-07 10:55:58

标签: java xml jaxb

我正在尝试让JAXB在编组过程中忽略包装类,在代码中使用这个包装类是有意义的,因为它将所有相关信息保存在一起,但是我需要在编组期间摆脱它处理。以下是相关代码。

@XmlType(name = "root")
@XmlRootElement(name = "root")
public class Root {

    @XmlElementRef
    private List<Resource> resources = new ArrayList<>();

    public void addResource(Resource resource) {
        resources.add(resource);
    }
}


@XmlRootElement(name = "", namespace = "")
@XmlAccessorType(XmlAccessType.NONE)
public class Resource {

    @XmlElementRef
    private Element element;
    @XmlElementRef
    private FieldType fieldType;
    @XmlElementRef
    private ListType listType;
}

Root是主要对象,Resource是我不想为其创建节点的包装器对象。我仍然希望渲染资源中的Element,FieldType和ListType。

这就是我目前所拥有的:

<root>
    <>
        <element name="resource1"/>
        <fieldType name="resource1--type">
        </fieldType>
        <listType name="resource--list">
        </listType>
    </>
    <>
        <element name="resource2"/>
        <fieldType name="resource2--type">
        </fieldType>
        <listType name="resource2--list">
        </listType>
    </>
</root>

我想要实现的目标如下:

<root>
    <element name="resource1"/>
    <fieldType name="resource1--type">
    </fieldType>
    <listType name="resource--list">
    </listType>
    <element name="resource2"/>
    <fieldType name="resource2--type">
    </fieldType>
    <listType name="resource2--list">
    </listType>
</root>

我不知道是否可能,但任何帮助都会受到赞赏。

感谢。

3 个答案:

答案 0 :(得分:5)

你无法在JAXB中实现这一点。即使您能够像这样序列化,例如使用XmlAdapter,也无法对其进行反序列化。

试试这个:

@XmlType(name = "root")
@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.NONE)
public class Root {

    private ArrayList<Resource> resources = new ArrayList<Resource>();

    public void addResource(Resource resource) {
        resources.add(resource);
    }

    @XmlElementRefs(value = { @XmlElementRef(type = Element.class),
                              @XmlElementRef(type = ListType.class),
                              @XmlElementRef(type = FieldType.class) })
    public List<Object> getResourceFields() {
        List<Object> list = new ArrayList<Object>();
        for (Resource r : resources) {
            list.add(r.getElement());
            list.add(r.getFieldType());
            list.add(r.getListType());
        }
        return list;
    }
}

基本上getRerourceFields连接同一列表中的所有资源字段。 如果您无法更改Root课程,则可能是RootAdapter,并将其用作@Biju建议。

答案 1 :(得分:2)

您可能必须为Root类创建一个XmlAdapter,此适配器应基本上将您的根实例映射到另一种类型,您可以在编组之前展平根结构 - 沿着这些行:

public class CustomRootAdapter extends
                    XmlAdapter<CustomRoot,Root>> {
@Override
public Root unmarshal(CustomRoot v) throws Exception {
    return null;//if you are not keen on unmarshalling..
}
@Override
public CustomRoot marshal(Root v) throws Exception {
    return ...;
}    

}

您可以使用以下方式注册此自定义适配器:

@XmlJavaTypeAdapter(CustomRootAdapter.class)与您的Root班级

答案 2 :(得分:-1)

这听起来就像@XMLTransient那样。

  

当放在类上时,它表示该类本身不应映射到XML。此类上的属性将与其派生类一起映射到XML,就好像该类是内联的一样。

请参阅javadoc