5

我试图让 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 是我不希望为其创建节点的包装器对象。但是,我仍然希望呈现 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>

我不知道这是否可能,但任何帮助将不胜感激。

谢谢。

4

3 回答 3

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 的建议使用它。

于 2012-06-07T12:09:05.167 回答
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班级

于 2012-06-07T13:17:23.667 回答
-1

这听起来正是@XMLTransient如此。

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

参见javadoc

于 2012-06-07T11:10:49.167 回答