通过JAXB解析可选的嵌套XML元素

时间:2016-06-23 13:18:42

标签: java xml spring spring-boot jaxb

我有XML输入,基本上看起来像这样:

<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<object label="" Property1="43" id="2">
  <mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
    <mxGeometry x="196" y="161" width="200" height="30" as="geometry"/>
  </mxCell>
</object>
<object label="" Property2="Helloooo" id="3">
  <mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
    <mxGeometry x="192" y="269" width="200" height="30" as="geometry"/>
  </mxCell>
</object>
<object label="" Property3="23" id="4">
  <mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
    <mxGeometry x="210" y="383" width="200" height="30" as="geometry"/>
  </mxCell>
</object>
</root>
</mxGraphModel>

我试图通过JAXB解析此输入:

MxGraphModel.java:

@XmlRootElement(name = "mxGraphModel")
@XmlAccessorType(XmlAccessType.FIELD)
public class MxGraphModel {

    @XmlElementWrapper(name = "root")

    @XmlElement(name = "object")
    private ArrayList<MxObject> mxObjects;

    @XmlElement(name = "mxCell")
    private ArrayList<MxCell> mxCells;

    //getters and setters...
}

MxObject.java:

@XmlAccessorType(XmlAccessType.FIELD)
public class MxObject {

    @XmlAttribute
    private String id;

    @XmlAttribute
    private String label;

    @XmlAttribute
    private String documentName;

    @XmlAttribute
    private String documentDescription;

    @XmlElement
    private MxCell mxCell;

    //getters and setters...
}

MxCell.java:

@XmlAccessorType(XmlAccessType.FIELD)
public class MxCell {

    @XmlAttribute
    private String id;

    @XmlAttribute
    private String parent;

    @XmlAttribute
    private String value;

    @XmlAttribute
    private String style;

    @XmlAttribute
    private String vertex;

    @XmlElement(name = "mxGeometry")
    private MxGeometry geometry;

    //getters and setters...
}

DemoController.java:

@RestController
@RequestMapping("/xml")
public class DemoController {
    @RequestMapping(method = RequestMethod.POST, consumes = {MediaType.APPLICATION_XML_VALUE})
    public void parseXML(@RequestBody MxGraphModel mxGraphModel) {
        //mxGraphModel contains EITHER objects of type MxObject 
        //OR
        //MxCell
    }
}

我的问题是,解析操作导致MxGraphModel对象包含对象集合或mxCell集合 - 但从不两者兼而有之。 在我看来,我声明XmlElements(&#34;对象&#34;和#34; mxCell&#34;)的顺序与解析结果相关。当我在对象之前声明mxCell时,正在解析2个mxCell(这是正确的),但是对象集合保持为空。反过来说。 是否可以解析两个XmlElements?我不知道问题是否与对象元素本身可能包含mxCell元素这一事实有关...

感谢。

1 个答案:

答案 0 :(得分:0)

@Dimpre Jean-Sébastien:

你是完全正确的,对不起这么晚发布答案。 解决方案不是使用根ElementWrapper

所以不要使用

@XmlElementWrapper(name = "root")

我必须在MxGraphModel.java中创建一个根XmlElement:

@XmlElement(name = "root")
private MxRoot mxRoot;

此外,我创建了一个名为MxRoot.java的文件,并将所有集合移到其中:

MxRoot.java:

@XmlAccessorType(XmlAccessType.FIELD)
public class MxRoot {
    @XmlElement(name = "UserObject")
    private ArrayList<MxObject> mxUserObjects;

    @XmlElement(name = "object")
    private ArrayList<MxObject> mxObjects;

    //XmlElement sets the name of the entities
    @XmlElement(name = "mxCell")
    private ArrayList<MxCell> mxCells;

    //getters and setters...
}

似乎@XmlWrapper Annotation只需要一个集合。它并不意味着包装多个集合(现在我知道它是有道理的:))

感谢所有人!