mar*_*hon 5 java jaxb xml-serialization
更新 - 请参阅底部的编辑
IDRefs/keyrefs似乎可以在JAXB注释中使用,但ref最终是元素文本.
我希望ref成为元素的属性.
例如,给定此对象模型:
@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;
}
Run Code Online (Sandbox Code Playgroud)
我希望外化的xml格式最终看起来像这样:
<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>
Run Code Online (Sandbox Code Playgroud)
相反,我能做的最好的就是这个(使用上面java代码中列出的注释):
<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>
Run Code Online (Sandbox Code Playgroud)
有没有办法可以强制idref值成为员工的属性,而不是元素正文?我知道我可以用XML Schema做到这一点,但是如果可能的话我想坚持注释.
谢谢.
编辑 Torious下面的解决方案几乎可以正常工作,但在某些情况下它并不能完全正常工作.
如果"office"元素位于(在xml文件中)办公室引用的"employee"元素之前,则解组失败.找不到员工引用,EmployeeRef包装器具有null员工对象.如果"员工"是第一个,它就有效.
这不会是一个很大的问题,但是编组方法会先把"办公室"放在首位,这样试图解组刚刚编组的东西就会失败.
在Torious的回答中编辑2评论解决了订购问题.
解决方案是使用XmlAdapter将 an 包装Employee在新类型 的实例中的 ,EmployeeRef它指定如何映射 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;
}
}
Run Code Online (Sandbox Code Playgroud)
祝你好运。
| 归档时间: |
|
| 查看次数: |
6177 次 |
| 最近记录: |