我有以下类(class)
@XmlRootElement(name = "entity")
public class Entity {
@XmlElementRef
protected AtomLink first;
@XmlElementRef
protected AtomLink second;
public Entity() {
}
public Entity(AtomLink first, AtomLink second) {
this.first = first;
this.second = second;
}
}
这是我的测试代码:
Entity entity = new Entity(new AtomLink("first", "http://test/first"), new AtomLink("second", "http://test/second"));
JAXBContext context;
try {
context = JAXBContextFactory.createContext(new Class[] { Entity.class } , null);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(entity, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
MOXy 的输出是错误的,因为缺少第一个链接:
<entity xmlns:atom="http://www.w3.org/2005/Atom">
<atom:link rel="second" href="http://test/second"/>
</entity>
Java JAXB RI 的输出是正确的:
<entity xmlns:atom="http://www.w3.org/2005/Atom">
<atom:link rel="first" href="http://test/first"/>
<atom:link rel="second" href="http://test/second"/>
</entity>
它是 MOXy 中的错误吗?
最佳答案
注意:我是 EclipseLink JAXB (MOXy) JAXB (JSR-222) 的领导和成员专家组。
Is it a bug in MOXy?
不,不是真的。问题在于,同时使用 @XmlElementRef
注释的相同类型的两个属性是无效的。如果您使用 JAXB RI 解码:
<entity xmlns:atom="http://www.w3.org/2005/Atom">
<atom:link rel="first" href="http://test/first"/>
<atom:link rel="second" href="http://test/second"/>
</entity>
然后像 MOXy 一样将其编码出来,您将得到:
<entity xmlns:atom="http://www.w3.org/2005/Atom">
<atom:link rel="second" href="http://test/second"/>
</entity>
解决方法 - 任何 JAXB (JSR-222) 实现
在 JAXB 中,重复元素应该在集合属性中表示:
@XmlRootElement
public class Entity {
@XmlElementRef
protected List<AtomLink> first;
public Entity() {
}
}
使用 MOXy 的 @XmlPath
下面是一个示例,说明如何利用 MOXy 的 @XmlPath
扩展来支持此用例。
包信息
假设您在 @XmlSchema
注释中指定了以下命名空间信息。
@XmlSchema(
xmlns={
@XmlNs(prefix="atom", namespaceURI="http://www.w3.org/2005/Atom")
}
)
package forum14998000;
import javax.xml.bind.annotation.*;
实体
然后您可以使用@XmlPath
将字段映射到具有特定属性值的元素。因为我们匹配的不仅仅是元素名称/URI,所以我们不会遇到原来的问题。
package forum14998000;
import javax.xml.bind.annotation.*;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name = "entity")
public class Entity {
@XmlPath("atom:link[@rel='first']")
protected AtomLink first;
@XmlPath("atom:link[@rel='second']")
protected AtomLink second;
public Entity() {
}
public Entity(AtomLink first, AtomLink second) {
this.first = first;
this.second = second;
}
}
AtomLink
既然 rel
属性包含在 @XmlPath
注释中,我们就不会将它作为一个字段包含在 AtomLink
类中。
import javax.xml.bind.annotation.*;
@XmlRootElement(namespace="http://www.w3.org/2005/Atom", name="link")
@XmlAccessorType(XmlAccessType.FIELD)
public class AtomLink {
@XmlAttribute
private String href;
}
了解更多信息
关于java - 只有一个 XMLElementRef 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14998000/