JAXB注释 - 如何创建XmlIDRef元素列表,将id值作为属性而不是元素正文文本? [英] JAXB Annotations - How do I make a list of XmlIDRef elements have the id value as an attribute instead of element body text?

查看:137
本文介绍了JAXB注释 - 如何创建XmlIDRef元素列表,将id值作为属性而不是元素正文文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新 - 请参阅底部的修改

IDX / IDreffs似乎可以在JAXB注释中使用,但是最终结果是元素text。

IDRefs/keyrefs seem to be possible in JAXB annotations, but the ref ends up being element text.

我希望ref成为元素的属性。

I would like the ref to be an attribute of an element.

例如,给定此对象模型:

For example, given this object model:

@XmlType
public class Employee {
    @XmlID
    @XmlAttribute
    String name;
    @XmlAttribute
    int years;
    @XmlAttribute
    String foo;
}

@XmlType
public class Office {
    @XmlAttribute
    String name;
    @XmlElementWrapper
    @XmlElement(name = "employee")
    List<Employee> employees;
}

@XmlRootElement
public class Company {
    @XmlElementWrapper
    @XmlElement(name = "office")
    List<Office> offices;
    @XmlElementWrapper
    @XmlElement(name = "employee")
    List<Employee> employees;
}

我希望外部化的xml格式最终看起来像这样:

I would like the externalized xml format to end up looking like this:

<company>
    <offices>
        <office name="nyc">
            <employees>
                <!--*** id ref to employee name ***-->
                <employee ref="alice"/>
                <employee ref="bob"/>
            </employees>
        </office>
        <office name="sf">
            <employees>
                <employee ref="connie"/>
                <employee ref="daphne"/>
            </employees>
        </office>
    </offices>
    <employees>
        <!-- *** name is the id *** -->
        <employee name="alice" years="3" foo="bar"/>
        <employee name="bob" years="3" foo="bar"/>
        <employee name="connie" years="3" foo="bar"/>
        <employee name="daphne" years="3" foo="bar"/>
    </employees>
</company>

相反,我能做的最好的就是这个(带有上面java代码中的注释):

Instead, the best I can do is this (with the annotations listed above in the java code):

<company>
    <offices>
        <office name="nyc">
            <employees>
                <employee>alice</employee>
                <employee>bob</employee>
            </employees>
        </office>
        <office name="sf">
            <employees>
                <employee>connie</employee>
                <employee>daphne</employee>
            </employees>
        </office>
    </offices>
    <employees>
        <employee name="alice" years="3" foo="bar"/>
        <employee name="bob" years="3" foo="bar"/>
        <employee name="connie" years="3" foo="bar"/>
        <employee name="daphne" years="3" foo="bar"/>
    </employees>
</company>

有没有办法可以强制idref值成为员工的属性,而不是元素体文本?我知道我可以用XML Schema做到这一点,但是如果可能的话我想坚持注释。

Is there a way I can force the idref value to be an attribute of employee, rather than element body text? I know I can do this with an XML Schema, but I'd like to stick to annotations if at all possible.

谢谢。

编辑以下Torious的解决方案几乎可以正常运行,但在某些情况下它不能正常工作。

Edit The solution by Torious below almost works, but it doesn't quite work under some circumstances.

如果office元素位于(在xml文件中)办公室引用的employee元素之前,则解组失败。找不到员工引用,EmployeeRef包装器具有null员工对象。如果员工是第一个,它就可以工作。

unmarshalling fails if the "offices" elements come before (in the xml file) the "employee" elements that the office references. The employee references are not found, and the EmployeeRef wrapper has a null employee object. If the "employee" are first, it works.

这不会是一个问题,但是编组方法会将办公室放在首位,这样试图解组刚刚编组的内容失败。

This wouldn't be so much of a problem, but the marshal method will put "offices" first, so that trying to unmarshal what has just been marshalled fails.

编辑2 评论Torious'的答案解决了订购问题。

Edit 2 comment in Torious' answer solves the ordering problem.

推荐答案

解决方案是使用 XmlAdapter 包装 Employee 在一个新类型的实例中, EmployeeRef ,它指定如何映射XML id ref:

The solution is to use an XmlAdapter which wraps an Employee in an instance of a new type, EmployeeRef, which specifies how to map the XML id ref:

@XmlType
public class Office {

    @XmlAttribute
    String name;

    @XmlElementWrapper
    @XmlElement(name="employee")
    @XmlJavaTypeAdapter(EmployeeAdapter.class) // (un)wraps Employee
    List<Employee> employees;
}

@XmlType
public class EmployeeRef {

    @XmlIDREF
    @XmlAttribute(name="ref")
    Employee employee;

    public EmployeeRef() {
    }

    public EmployeeRef(Employee employee) {
        this.employee = employee;
    }
}

public class EmployeeAdapter extends XmlAdapter<EmployeeRef, Employee> {

    @Override
    public EmployeeRef marshal(Employee employee) throws Exception {
        return new EmployeeRef(employee);
    }

    @Override
    public Employee unmarshal(EmployeeRef ref) throws Exception {
        return ref.employee;
    }
}

祝你好运。

这篇关于JAXB注释 - 如何创建XmlIDRef元素列表,将id值作为属性而不是元素正文文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆