【问题标题】:JAXB: Use @XmlIDREF on a MapJAXB:在地图上使用 @XmlIDREF
【发布时间】:2016-09-14 09:05:03
【问题描述】:


我正在尝试使用 JAXB 编组一些数据。我的问题如下: 我有一个 Frame 类,其中包含信号图。

@XmlRootElement(name = "frame")
@XmlAccessorType(XmlAccessType.FIELD)
public class Frame extends V_Element {


    @XmlElementWrapper(name = "signals")
    private Map<Signal, Double> signals;

}

到目前为止,XML 输出是:

    <frame id="ee61b926-a1ca-4462-ac58-77d3ac0cbe5e" name="F1">
        <signals>
            <entry>
                <key id="7352beaa-1921-4bfe-b1ce-3d8dabe69e8b" name="Signal1">
                    <properties/>
                    <bitLength>0</bitLength>
                    <frame>3ee61b926-a1ca-4462-ac58-77d3ac0cbe5e</frame>
                </key>
                <value>1.0</value>
            </entry>
        </signals>
    </frame>

但我想拥有以下架构:

    <frame id="3ee61b926-a1ca-4462-ac58-77d3ac0cbe5e" name="F1">

        <signals>
            <signal pos= "1.0">7352beaa-1921-4bfe-b1ce-3d8dabe69e8b</sgnal>
        </signals>
    </frame>

在框架标签下,我只想将信号 ID 和 pos 值作为属性。 @XmlIDREF 注释不适用于地图。

Signal 和 Frame 之间的关系是多对多的关系,因此一个 Signal 在不同的 Frames 中具有不同的位置。 有什么线索吗?

【问题讨论】:

    标签: java xml jaxb marshalling


    【解决方案1】:

    为了获得这种输出,您的 POJO 可能看起来像

    @XmlAccessorType(XmlAccessType.FIELD)
    public class Signal {
    
        @XmlAttribute(name = "pos", required=true)
        private Double pos;
        @XmlValue
        private String id;
    
        public String getId(){
            return id;
        }
        public Double getPos(){
            return pos;
        }
        public void setPos(Double p){
            pos = p;
        }
        public void setId(String id){
            this.id = id;
        }
    }
    
    
    public class SignalWrapper {
    
        @XmlElement(name="signal", required=true)
        private List<Signal> signalList;
    
        public List<Signal> getSignalList(){
            if(signalList == null)
                signalList = new ArrayList<>();
    
            return signalList;
        }
      //no setter for Signal list is necessary
    
    }
    
    @XmlRootElement(name="frame")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Frame {
    
        @XmlAttribute(name="id", required=true)
        private String id;
    
        @XmlAttribute(name="name", required=true)
        private String name;
    
        @XmlElement(name="signals", required=true)
        private SignalWrapper sigWrapper;
    
        public String getId(){
            return id;
        }
        public String getName(){
            return name;
        }
        public void setName(String name){
            this.name = name;
        }
        public void setId(String id){
            this.id = id;
        }
    
        public SignalWrapper getSigWrapper(){
            return sigWrapper;
        }
        public void setSignalWrapper(SignalWrapper sw){
            sigWrapper = sw;
        }
    
    
    }
    

    您的测试代码可能如下所示

    final String ENT_XML = "C:\\test\\Signal.xml";
    
                JAXBContext context = JAXBContext.newInstance(Frame.class);
    
                  Marshaller m =  context.createMarshaller();
    
                  Signal s = new Signal();
                  s.setId("7352beaa-1921-4bfe-b1ce-3d8dabe69e8b");
                  s.setPos(2.0);
    
                  SignalWrapper sw = new SignalWrapper();
    
                  List<Signal> sl = sw.getSignalList();
                  sl.add(s);
    
                  Frame f = new Frame();
                  f.setSignalWrapper(sw);
                  f.setId("3ee61b926-a1ca-4462-ac58-77d3ac0cbe5e");
                  f.setName("F1");
    
                  m.marshal(f, new File(ENT_XML));
    

    【讨论】:

    • 感谢@dsp_user 的回复。由于信号和帧之间的关系是多对多关系,所以我不能将 pos 属性放在 Signal POJO 中。一个信号在不同的帧中有不同的位置。抱歉,我不是很清楚。
    【解决方案2】:

    我已经设法获得了我想要的架构。我添加了一个类 SignalPos

    public class SignalPos {
    
        @XmlAttribute(name = "id")
        @XmlIDREF
        private Signal signal;
        @XmlAttribute
        private Double pos;
    
        public SignalPos() {
        }
    
        public SignalPos(Signal s, double pos) {
            this.signal = s;
            this.pos = pos;
        }
    
        public Signal getSignal() {
            return signal;
        }
    
        public Double getPos() {
            return pos;
        }
    
    }
    

    Frame类中

    public class Frame {
        @XmlElementWrapper(name = "signals")
        @XmlElement(name = "signal")
        private List<SignalPos> signals;
    
    }
    

    输出:

        <signals>
            <signal id="d1c23562-d02c-439a-8e7b-d4222c7750c8" pos="23.0"/>
            <signal id="932d8850-36e3-467b-8a62-1e0ae6bb271a" pos="2.0"/>
            <signal id="2e6a99b2-95f8-4a5f-bf44-1ce948839e9d" pos="1.0"/>
        </signals>
    

    【讨论】:

    • 此输出与您在原始帖子中的输出略有不同(如果那是您想要的,很好:)
    猜你喜欢
    • 2012-05-07
    • 1970-01-01
    • 2021-10-27
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多