在Java中读取xml文件 - 仅选择元素

时间:2017-06-26 16:54:29

标签: java xml jaxb

我刚开始学习如何从XML创建java对象。但是,现在我有一个棘手的输入,我真的不知道如何解决它。

这是输入:

<?xml version="1.0" encoding="UTF-8"?>
<return>
  <productChange cd_product="711" ds_product="MBL40337 I151 BLACK P" cd_species="UN" cd_tipi="61062000" cd_cst="5" qt_weight="" cd_nbm="" dt="2016-05-04 11:47:36">
    <productvalue cd_company="1" cd_product="711" tp_value="P" cd_value="1" vl_product="61.39">
      <tipovaluePrd tp_value="P" cd_value="1" ds_value="SALE" cd_corrency="1" />
    </productvalue>
    <productvalue cd_company="1" cd_product="711" tp_value="P" cd_value="4" vl_product="129.8">
      <tipovaluePrd tp_value="P" cd_value="4" ds_value="SALE STORE" cd_corrency="1" />
    </productvalue>
    <productvalue cd_company="1" cd_product="711" tp_value="P" cd_value="5" vl_product="64.9">
      <tipovaluePrd tp_value="P" cd_value="5" ds_value="SALE AT" cd_corrency="1" />
    </productvalue>
    <productvalue cd_company="1" cd_product="711" tp_value="P" cd_value="8" vl_product="122.78">
      <tipovaluePrd tp_value="P" cd_value="8" ds_value="SALE FQ" cd_corrency="1" />
    </productvalue>
  </productChange>
</return>

要使用JaxB(由第三方公司提供的XML)使用此xml,我构建了以下类:

@XmlAccessorType(XmlAccessType.FIELD)
public class ProductUpdateResponse {

  @XmlAttribute(name = "cd_product")
  private Integer productCode;
  @XmlAttribute(name = "ds_product")
  private String productDescription;
  @XmlAttribute(name = "cd_species")
  private String productSpecie;
  @XmlAttribute(name = "cd_tipi")
  private Integer productTIPI;
  @XmlAttribute(name = "cd_cst")
  private Integer productCST;
  @XmlAttribute(name = "qt_weight")
  private String productWeight;
  @XmlAttribute(name = "cd_nbm")
  private String productNBM;
  @XmlAttribute(name = "dt")
  private String productDate;

  @XmlElement(name = "productvalue")
  private ProductValueType productValue;
// getters and setters
}

@XmlAccessorType(XmlAccessType.FIELD)
public class ProductValue {
  @XmlAttribute(name = "cd_product")
  private Integer productCode;
  @XmlAttribute(name = "cd_company")
  private Integer companyCode;
  @XmlAttribute(name = "tp_value")
  private String valueType;
  @XmlAttribute(name = "cd_value")
  private Integer valueCode;
  @XmlAttribute(name = "vl_product")
  private BigDecimal productValue;

  @XmlElement(name = "tipovaluePrd")
  private ProductValueType productValueType;
//getters and seters
}

@XmlAccessorType(XmlAccessType.FIELD)
public class ProductValueType {
  @XmlAttribute(name = "tp_value")
  private String valueType;
  @XmlAttribute(name = "cd_value")
  private String valueCode;
  @XmlAttribute(name = "ds_value")
  private String valueDescription;
  @XmlAttribute(name = "cd_corrency")
  private Integer valueCurrency;
//getters and seters
}

但是,对我来说,主要信息是null(productvalue)我想知道是否因为xml中有四个标签productvalue(我只需要tipovaluePrd.cd_value4的那个})。

以下是我用来解析XML的方法:

private ProductUpdateResponse buildResponse(String rawResponse, Class<T> responseClass) {

    JAXBContext jaxbContext = null;
    try {
      jaxbContext = JAXBContext.newInstance(responseClass);
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      StringReader reader = new StringReader(rawResponse);
      return (ProductUpdateResponse) unmarshaller.unmarshal(reader);
    } catch (JAXBException | ClassCastException e) {
      return null;
    }
  }

所以,我想知道是否有办法专门读取我想要的值(productvalue元素tipovaluePrd.cd_value = 4),我怎么能这样做。如果没有,我应该如何建立我的课程以便我能正确阅读所有内容?

此处无法更改输入...

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我真的很惊讶你从当前的设置中获得了JAXB的结果。

你缺少一个代表根元素的类:

@XmlRootElement(name="return")
@XmlAccessorType(XmlAccessType.FIELD)
public class Return {
     @XmlElement(name="productchange")
     private ProductUpdateResponse response;

     //getters and setters
}

此外,在您的ProductUpdateResponse类中,您应该更改:

@XmlElement(name = "productvalue")
private ProductValueType productValue;

通过

@XmlElement(name = "productvalue")
private List<ProductValue> productValues;

最后,在buildResponse方法中,确保responseClass参数为Return.class。

有了这个,你应该有一个包含所有productvalue元素的列表。您只需从中获得您感兴趣的产品价值。

如果您只想获得您感兴趣的元素:

  1. 正如swasa建议的那样,您可以使用javax.xml.xpath在XML上发出Xpath请求。

  2. 如果您愿意更改JAXB实现:EclipseLink JAXB实现实现了一个@XmlPath批注,允许您根据XPath请求绑定对象:

    @XmlPath(name = "productvalue/tipovaluePrd[@cd_value=4]")
    private ProductValueType productValueType;