代码之家  ›  专栏  ›  技术社区  ›  Herr-Herner

仅整理了一个XMLElementRef

  •  2
  • Herr-Herner  · 技术社区  · 11 年前

    我有以下课程

    @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中的一个bug吗?

    1 回复  |  直到 11 年前
        1
  •  1
  •   bdoughan    11 年前

    注: 我是 EclipseLink JAXB (MOXy) 领导和 JAXB (JSR-222) 专家组。

    这是MOXy中的一个bug吗?

    不,不是真的。问题是,将两个相同类型的属性都用注释是无效的 @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(XmlPath) 扩展来支持这个用例。

    程序包信息

    假设您在 @XmlSchema 注释。

    @XmlSchema(
        xmlns={
           @XmlNs(prefix="atom", namespaceURI="http://www.w3.org/2005/Atom")
        }
    )
    package forum14998000;
    
    import javax.xml.bind.annotation.*;
    

    实体

    然后你可以使用 @XmlPath(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;
        }
    
    }
    

    原子链接

    现在 rel 属性包含在 @XmlPath(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;
    
    }
    

    了解更多信息