JAXB:在地图上使用@XmlIDREF

时间:2016-09-14 09:05:04

标签: java xml jaxb marshalling


我试图用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>

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

信号和帧之间的关系是多对多关系,因此信号在不同的帧中具有不同的位置。 任何线索?

2 个答案:

答案 0 :(得分: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));

答案 1 :(得分:0)

我设法获得了我想要的架构。我添加了一个 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;
    }

}

框架

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>