java - 只有一个 XMLElementRef 编码

标签 java jaxb moxy

我有以下类(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/

相关文章:

java - Eclipse Juno 4.2 的 Swing 插件

java - 使用 JAXB 通过 SOAP 传递 HashMap<String,Object>

java - XmlAdapter 和 JSON 的 MOXy 异常

java - 将 Nifi 属性值拆分为多个属性

java - 如何在客户端/服务器 Java 应用程序中传输文件

java - JAXB 编码异常

java - JAXB:使用包含较少属性的 XSD 从 Java 生成 XML

java - 使用 Jersey 和 MOXy 将 JSON 反序列化为列表集合

json - @XmlInverseReference 注释不起作用

java - 尝试使用 akka 流编码(marshal) jaxb 对象时出现空文件