简体   繁体   English

为什么JAXB java xml unmarshaller返回null

[英]why JAXB java xml unmarshaller return null

I am trying to unmarshal XML to java class as follows:- 我正在尝试将XML解组为Java类,如下所示:

My xml file as follows:- 我的xml文件如下:

<Features_res>
   <StartWeek>202017</StartWeek>
  <EndWeek>202035</EndWeek>
  <Pno12>ABCDEEB</Pno12>

  <FeatureList>
      <Feature>
            <Code>T002</Code>
       </Feature>
         <Feature>
          <Code>T002</Code>
       </Feature>
    </FeatureList>
</Features_res>

Java InteriorResponse:- Java InteriorResponse:-

@XmlRootElement(name = "Features_res")
public class InteriorResponse {

@XmlElement(name = "StartWeek")
private int sWeek;
@XmlElement(name = "EndWeek")
private int eWeek;
@XmlElement(name = "Pno12")
private String p12;
List<Feature> featureList;

public InteriorResponse() {
}

public InteriorResponse(int startWeek, int endWeek, String pno12) {
    super();
    this.sWeek = startWeek;
    this.eWeek = endWeek;
    this.p12 = pno12;
}

public int getStartWeek() {
    return sWeek;
}
public void setStartWeek(int startWeek) {
    this.sWeek = startWeek;
}
public int getEndWeek() {
    return eWeek;
}
public void setEndWeek(int endWeek) {
    this.eWeek = endWeek;
}
public String getPno12() {
    return p12;
}
public void setPno12(String pno12) {
    this.p12 = pno12;
}
public List<Feature> getFeatureList() {
    return featureList;
}

@XmlElement(name = "FeatureList")
public void setFeatureList(List<Feature> featureList) {
    this.featureList = featureList;
}           
 }

Another Java Feature:- 另一个Java功能:

@XmlRootElement(name = "Feature")
 public class Feature {
//@XmlElement(name = "Feature")
private String feature_;
@XmlElement(name = "code")
private String code_;

public String getCode() {
    return code_;
}

public void setCode(String code) {
    this.code_ = code;
}

public String getFeature_() {
    return feature_;
}

public void setFeature_(String feature_) {
    this.feature_ = feature_;
}
 }

I am using above class as :- 我正在上课使用:-

    public static void xmlToInterior() {
    File file = new File("minxml.xml");
    JAXBContext jaxbContext;

    try {
        jaxbContext = JAXBContext.newInstance(InteriorResponse.class);
        Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        InteriorResponse interiorFeatures = (InteriorResponse) unmarshaller.unmarshal(file);
        List<Feature> list_feat =  interiorFeatures.getFeatureList();
        for(Feature ft : list_feat) {
            System.out.println(ft.getCode());
        }
    } catch (JAXBException e) {
        e.printStackTrace();
    }       
 }

Output I have as:- list_feat 输出我有:-list_feat
code_ null code_ null
feature_ null feature_ null

And list_feat has size 1. It should 2. 并且list_feat的大小为1。应该为2。

Also I have to name class member sWeek instead of startWeek. 另外,我必须命名类成员sWeek而不是startWeek。 Otherwise, jaxbContext = JAXBContext.newInstance(InteriorResponse.class) throws exception like 2 element exist with same name. 否则,jaxbContext = JAXBContext.newInstance(InteriorResponse.class)会引发异常,例如存在两个具有相同名称的元素。

XML additional part XML附加部分

I thought I could do the reaming part of the XML. 我以为我可以做XML的扩孔部分。 I was trying part by part. 我正在部分地尝试。 But I couldn't do it. 但是我做不到。 I really need to find some good tutorial or book about JXB. 我真的需要找到一些有关JXB的好的教程或书。 All I find a short overview of JXB. 我所发现的只是JXB的简短概述。 Any suggestion about where to read in details? 关于在哪里详细阅读有什么建议吗?

<Features_res>
<StartWeek>202017</StartWeek>
<EndWeek>202035</EndWeek>
<Pno12>ABCDEEB</Pno12>

<FeatureList>
    <Feature>
        <Code>T002</Code>
    </Feature>
    <Feature>
        <Code>T002</Code>
    </Feature>
</FeatureList>

 <OptionList>
    <Option>001048</Option>
    <Option>000050</Option>
    <Option>000790</Option>
 </OptionList>  
</Features_res>

So I made new class as:- 所以我上了新课:

    public class OptionList {

    private List<Option> options;

    @XmlElement(name = "Option")
    public List<Option> getOptions() {
        return options;
    }

    public void setOptions(List<Option> options) {
        this.options = options;
    }
}

Another class as :- 另一类为:-

    import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;

public class Option {

    @XmlElement(name = "Option")
    private String option_;

    public String getOption() {
        return option_;
    }


    public void setOption(String option) {
        this.option_ = option;
    }   
}

And updated for InteriorResponse class as:- 并已针对InteriorResponse类更新为:-

    import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Features_res")
public class InteriorResponse {

  @XmlElement(name = "StartWeek")
  private int sWeek;

  @XmlElement(name = "EndWeek")
  private int eWeek;

  @XmlElement(name = "Pno12")
  private String p12;

  private FeatureList featureList;

  private OptionList optionList;

  public InteriorResponse() {}

  public InteriorResponse(int startWeek, int endWeek, String pno12) {
    super();
    this.sWeek = startWeek;
    this.eWeek = endWeek;
    this.p12 = pno12;
  }

  public int getStartWeek() {
    return sWeek;
  }

  public void setStartWeek(int startWeek) {
    this.sWeek = startWeek;
  }

  public int getEndWeek() {
    return eWeek;
  }

  public void setEndWeek(int endWeek) {
    this.eWeek = endWeek;
  }

  public String getPno12() {
    return p12;
  }

  public void setPno12(String pno12) {
    this.p12 = pno12;
  }

  @XmlElement(name = "FeatureList")
  public FeatureList getFeatureList() {
    return featureList;
  }

  public void setFeatureList(FeatureList featureList) {
    this.featureList = featureList;
  }

  @XmlElement(name = "OptionList")
  public OptionList getOptionList() {
    return optionList;
}

public void setOptionList(OptionList optionList) {
    this.optionList = optionList;
}

@Override
  public String toString() {
    return "InteriorResponse{"
        + "sWeek="
        + sWeek
        + ", eWeek="
        + eWeek
        + ", p12='"
        + p12
        + '\''
        + ", featureList="
        + featureList
        + '}';
  }
}

I couldn't get the Option. 我无法选择。 option null 选项为空

The total xml is really huge. 总的xml确实很大。 I still would like to try the remaing parts by myself part by part. 我仍然想单独尝试其余部分。

You need to design your classes according to XML structure. 您需要根据XML结构设计您的类。 Find below the classes. 在课程下方找到。

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "Features_res")
public class InteriorResponse {

  @XmlElement(name = "StartWeek")
  private int sWeek;

  @XmlElement(name = "EndWeek")
  private int eWeek;

  @XmlElement(name = "Pno12")
  private String p12;

  private FeatureList featureList;

  private OptionList optionList;

  public InteriorResponse() {}

  public InteriorResponse(int startWeek, int endWeek, String pno12) {
    super();
    this.sWeek = startWeek;
    this.eWeek = endWeek;
    this.p12 = pno12;
  }

  public int getStartWeek() {
    return sWeek;
  }

  public void setStartWeek(int startWeek) {
    this.sWeek = startWeek;
  }

  public int getEndWeek() {
    return eWeek;
  }

  public void setEndWeek(int endWeek) {
    this.eWeek = endWeek;
  }

  public String getPno12() {
    return p12;
  }

  public void setPno12(String pno12) {
    this.p12 = pno12;
  }

  @XmlElement(name = "FeatureList")
  public FeatureList getFeatureList() {
    return featureList;
  }

  public void setFeatureList(FeatureList featureList) {
    this.featureList = featureList;
  }

  @XmlElement(name = "OptionList")
  public OptionList getOptionList() {
    return optionList;
  }

  public void setOptionList(OptionList optionList) {
    this.optionList = optionList;
  }

  @Override
  public String toString() {
    return "InteriorResponse{"
        + "sWeek="
        + sWeek
        + ", eWeek="
        + eWeek
        + ", p12='"
        + p12
        + '\''
        + ", featureList="
        + featureList
        + ", optionList="
        + optionList
        + '}';
  }
}

Class for Feature object Feature对象的类

import javax.xml.bind.annotation.XmlElement;

public class Feature {

  @XmlElement(name = "Code")
  private String code_;

  public String getCode() {
    return code_;
  }

  public void setCode(String code) {
    this.code_ = code;
  }

  @Override
  public String toString() {
    return "Feature{" + "code_='" + code_ + '\'' + '}';
  }
}

Class for FeatureList FeatureList的类

import javax.xml.bind.annotation.XmlElement;
import java.util.List;

public class FeatureList {

  private List<Feature> features;

  @XmlElement(name = "Feature")
  public List<Feature> getFeatures() {
    return features;
  }

  public void setFeatures(List<Feature> features) {
    this.features = features;
  }
}

Class for OptionList OptionList的类别

import javax.xml.bind.annotation.XmlElement;
import java.util.List;

public class OptionList {
  private List<String> option;

  @XmlElement(name = "Option")
  public List<String> getOption() {
    return option;
  }

  public void setOption(List<String> option) {
    this.option = option;
  }
}

For testing and simplicity, I have written a small java test program below. 为了测试和简化,我在下面编写了一个小的Java测试程序。

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.util.List;

public class Test {

  public static void main(String[] args) {
    File file =
        new File("E:\\so\\xml\\minxml.xml");
    JAXBContext jaxbContext;

    try {
  jaxbContext = JAXBContext.newInstance(InteriorResponse.class);
  Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
  InteriorResponse interiorFeatures = (InteriorResponse) unmarshaller.unmarshal(file);

  List<Feature> list_feat = interiorFeatures.getFeatureList().getFeatures();

  List<String> optionList = interiorFeatures.getOptionList().getOption();
  for (String option : optionList) {
    System.out.println("Option Value : " + option);
  }

  for (Feature ft : list_feat) {
    System.out.println(ft.getCode());
  }
} catch (JAXBException e) {
  e.printStackTrace();
}
  }
}

I also provide the sample xml structure below. 我还在下面提供了示例xml结构。

    <Features_res>
    <StartWeek>202017</StartWeek>
    <EndWeek>202035</EndWeek>
    <Pno12>ABCDEEB</Pno12>

    <FeatureList>
        <Feature>
            <Code>T002</Code>
        </Feature>
        <Feature>
            <Code>T002</Code>
        </Feature>
    </FeatureList>

    <OptionList>
        <Option>001048</Option>
        <Option>000050</Option>
        <Option>000790</Option>
    </OptionList>
</Features_res>

I knew very little about JAXB stuff. 我对JAXB的知识知之甚少。 I have learned a lot from Sambit who helped a lot and gave me the way to start with this JAXB. 我从Sambit那里学到了很多东西,他提供了很多帮助,并为我提供了开始使用此JAXB的方法。 Later I have implemented my version with less number of Java class and more smart use of JAXB annotations. 后来,我用更少的Java类和更聪明地使用JAXB注释实现了我的版本。

My version of InteriorResponse class:- 我的InteriorResponse类:

    import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

@XmlRootElement(name = "Features_res")
public class InteriorResponse {

    @XmlElement(name = "StartWeek")
    private int startWeek;

    @XmlElement(name = "EndWeek")
    private int endWeek;

    @XmlElement(name = "Pno12")
    private String pno12;

    @XmlElementWrapper(name = "FeatureList")
    @XmlElement(name = "Feature")
    private List<Feature> featureList;

    @XmlElementWrapper(name = "OptionList")
    @XmlElement(name = "Option")
    private List<String> optionList;

    public InteriorResponse() {
    }

    public InteriorResponse(int startWeek, int endWeek, String pno12) {
        super();
        this.startWeek = startWeek;
        this.endWeek = endWeek;
        this.pno12 = pno12;
    }

    @XmlTransient
    public int getStartWeek() {
        return startWeek;
    }

    public void setStartWeek(int startWeek) {
        this.startWeek = startWeek;
    }

    @XmlTransient
    public int getEndWeek() {
        return endWeek;
    }

    public void setEndWeek(int endWeek) {
        this.endWeek = endWeek;
    }

    @XmlTransient
    public String getPno12() {
        return pno12;
    }

    public void setPno12(String pno12) {
        this.pno12 = pno12;
    }

    @XmlTransient
    public List<Feature> getFeatureList() {
        return featureList;
    }

    public void setFeatureList(List<Feature> featureList) {
        this.featureList = featureList;
    }

    @XmlTransient
    public List<String> getOptionList() {
        return optionList;
    }

    public void setOptionList(List<String> optionList) {
        this.optionList = optionList;
    }

    @Override
    public String toString() {
        return "InteriorResponse{" + "sWeek=" + startWeek + ", eWeek=" + endWeek + ", pno12='" + pno12 + '\'' + ", featureList=" + featureList + ", optionList="
            + optionList + '}';
    }
}

My version of Feature class:- 我的要素类版本:-

    import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;

public class Feature {

    @XmlElement(name = "Code")
    private String code;

    @XmlTransient
    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public String toString() {
        return "Feature{" + "code_='" + code + '\'' + '}';
    }
}

Note that I don't need any extra wrapper class for FeatuerList and OptionList. 请注意,对于FeatuerList和OptionList,我不需要任何额外的包装器类。 It can be done by the JAXB annotation @XmlElementWrapper(name = "FeatureList"). 可以通过JAXB批注@XmlElementWrapper(name =“ FeatureList”)来完成。 Also, a very important lesson learned. 此外,还吸取了非常重要的教训。 We have to mark all the property's getter method as @XmlTransient. 我们必须将所有属性的getter方法标记为@XmlTransient。 Otherwise, JAXB throws an exception 2 properties found with the same name. 否则,JAXB会抛出一个异常2,它们具有相同的名称。 Because our class all properties is visible to the JAXB. 因为我们的类的所有属性对于JAXB都是可见的。 So we have to mark one as @XmlTransient. 因此,我们必须将其标记为@XmlTransient。

In my opion, it is a better solution than the accepted answer. 在我看来,这是比公认的答案更好的解决方案。 I gave all the credit to Sambit. 我把一切归功于Sambit。 I hove this will help others. 我认为这会对他人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM