why JAXB java xml unmarshaller return null

131
August 02, 2019, at 09:30 AM

I am trying to unmarshal XML to java class as follows:-

My xml file as follows:-

<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:-

@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:-

@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
code_ null
feature_ null

And list_feat has size 1. It should 2.

Also I have to name class member sWeek instead of startWeek. Otherwise, jaxbContext = JAXBContext.newInstance(InteriorResponse.class) throws exception like 2 element exist with same name.

XML additional part

I thought I could do the reaming part of the 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. All I find a short overview of 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:-

    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. I still would like to try the remaing parts by myself part by part.

Answer 1

You need to design your classes according to XML structure. 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;
  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;
  }
  @Override
  public String toString() {
    return "InteriorResponse{"
        + "sWeek="
        + sWeek
        + ", eWeek="
        + eWeek
        + ", p12='"
        + p12
        + '\''
        + ", featureList="
        + featureList
        + '}';
  }
}

Class for Feature object

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

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;
  }
}

For testing and simplicity, I have written a small java test program below.

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();
      for (Feature ft : list_feat) {
        System.out.println(ft.getCode());
      }
    } catch (JAXBException e) {
      e.printStackTrace();
    }
  }
}

I also provide the sample xml structure below.

<Features_res>
    <StartWeek>202017</StartWeek>
    <EndWeek>202035</EndWeek>
    <Pno12>ABCDEEB</Pno12>
    <FeatureList>
        <Feature>
            <Code>T001</Code>
        </Feature>
        <Feature>
            <Code>T002</Code>
        </Feature>
    </FeatureList>
</Features_res>
Rent Charter Buses Company
READ ALSO
How to handle different users in different environments

How to handle different users in different environments

For a login page automation, a user need to enter user id, security answer and passwordDifferent environment have different users

106
StringBuilder.append(CharSequence) with no IOException? [duplicate]

StringBuilder.append(CharSequence) with no IOException? [duplicate]

This question already has an answer here:

131
What&#39;s the best way to store and cache items from large JSON files?

What's the best way to store and cache items from large JSON files?

I'm trying to find an efficient solution to how I can store and cache items from large JSON filesEach file includes different types of data, but in total, can span in about 10,000 different types of objects

120
How to use qualifier to decide the fields of a class?

How to use qualifier to decide the fields of a class?

I have created to Hazelcast map config in one instanceI have a bean method inside config which sends separate maps in 2 different methods

136