如何使用JAXB解析xml?

时间:2016-07-01 12:22:16

标签: java xml parsing jaxb jackson

我想使用JAXB将XML文件映射到对象。如何转换XML文件,如下所示:

<Contract>
    <Variable Name="Address">
        <Value>Address</Value>
    </Variable>
    <Variable Name="FirstName">
        <Value>First</Value>
    </Variable>
    <Variable Name="SecondName">
        <Value>Second</Value>
    </Variable>
    <Parameter Name="id">
        <Value>399425</Value>
    </Parameter>
    <Parameter Name="isComplete">
        <Value>True</Value>
    </Parameter>
    <Parameter Name="templateName">
        <Value>Probate Application</Value>
    </Parameter>
</Contract>

像这样的java对象:

public class Contract {
    private Long id;
    private String templateName;
    private boolean isComplete;
    private Map<String, String> answers = new HashMap<>();

}

或者也许建议一些教程。 谢谢

1 个答案:

答案 0 :(得分:1)

您有两个问题:将<Variable>元素绑定到Map并将<Parameter>元素绑定到不同类型的对象。

我会按此顺序处理问题。

对于地图,您必须使用XmlAdapter @XmlJavaTypeAdapter

对代表您的<Variable>元素的类进行编码并对其进行映射:

public class Variable{

    @XmlAttribute
    public String Name;

    @XmlElement
    public String Value;

    //Getters and setters
}

然后编写XmlAdapter:

public class YourAdapter extends XmlAdapter<List<Variable>,Map<String,String>>{

    public Map<String,String> unmarshall(List<Variable> arg0){
         //Logic to convert a List<Variable> into a Map<String,String> and return it
    }

    public List<Variable> marshall(Map<String,String> arg0){
         //Logic to convert a Map<String,String> into a List<Variable> and return it
    }


}

然后映射您的合同类:

@XmlRootElement
@XmlSeeAlso({Variable.class})
public class Contract{

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     //Getters and setters
}

有了这个,你的地图就可以了。

第二个问题有两个解决方案:使用JAXB参考实现或使用JAXB MOXy实现。

  

使用JAXB参考实现

JAXB Reference实现不能使用Xpath来进行绑定。所以这是一个解决方法。

为您的<Parameter>元素编写第二个类和适配器,除了名称之外基本上是相同的,并使用此映射进行合同:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Variable.class,Parameter.class})
public class Contract{

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     @XmlElement(name="Parameter")
     @XmlJavaTypeAdapter(YourAdapterForParameter.class)
     private Map<String,String> parameterMap;

     public Long getId(){
          return Long.valueOf(parameterMap.get("id"));
     }

     public void setId(Long id){
          parameterMap.put("id",id.toString());
     }

     //Same thing for other getters/setters
}
  

使用MOXy实现

使用MOXy实现,您可以使用@XmlPath和XPath使其更清晰:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({Variable.class})
public class Contract{

     @XmlPath("./Variable[@Name='id']/Value")
     private Long id;

     @XmlPath("./Variable[@Name='templateName']/Value")
     private String templateName;

     @XmlPath("./Variable[@Name='isComplete']/Value")
     private boolean isComplete;

     @XmlElement(name="Variable")
     @XmlJavaTypeAdapter(YourAdapter.class)
     private Map<String,String> map;

     //Getters and setters
}

有关详细信息/帮助,请参阅JAXB / MOXy文档。