I'm trying to unmarshal an a xml file. Here's my files below.
XML file
<AccountInfo>
<Account>
<FirstName>FirstName1</FirstName>
<LastName>LastName1</LastName>
<Country>US</Country>
<PhoneNumber>2022023111</PhoneNumber>
<Email>[email protected]</Email>
<Password>1222433123</Password>
<PaymentMethod>
<CardNumber>4111111111111111</CardNumber>
<Month>12</Month>
<Year>2017</Year>
<CVV>098</CVV>
<StreetAddress>test</StreetAddress>
<Town>test</Town>
<State>Virginia</State>
<ZipCode>12365</ZipCode>
<Country>US</Country>
</PaymentMethod>
</Account>
<Account>
<FirstName>FirstName1</FirstName>
<LastName>LastName1</LastName>
<Country>US</Country>
<PhoneNumber>2022023111</PhoneNumber>
<Email>[email protected]</Email>
<Password>1222433123</Password>
<PaymentMethod>
<CardNumber>4111111111111111</CardNumber>
<Month>12</Month>
<Year>2017</Year>
<CVV>098</CVV>
<StreetAddress>test</StreetAddress>
<Town>test</Town>
<State>Virginia</State>
<ZipCode>12365</ZipCode>
<Country>US</Country>
</PaymentMethod>
</Account>
</AccountInfo>
JaxbHelper.java
public static <T> T unmarshal(InputStream file, Class<T> unmarshalClass)
throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(unmarshalClass);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
T object = (T) jaxbUnmarshaller.unmarshal(file);
return object;
}
AccountInfo.java
@XmlRootElement(name = "AccountInfo")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlSeeAlso({PaymentMethod.class})
public class AccountInfo {
@XmlElement(name = "FirstName")
private String FirstName;
@XmlElement(name = "LastName")
private String LastName;
@XmlElement(name = "Country")
private String Country;
@XmlElement(name = "PhoneNumber")
private String PhoneNumber;
@XmlElement(name = "Email")
private String Email;
@XmlElement(name = "Password")
private String Password;
@XmlElement(name = "PaymentMethod")
private PaymentMethod paymentMethod;
public AccountInfo() {
setFirstName(null);
setLastName(null);
setCountry(null);
setPhoneNumber(null);
setEmail(null);
setPassword(null);
setPaymentMethod(null);
}
public AccountInfo(String FirstName, String LastName, String Country, String PhoneNumber, String Email, String Password, PaymentMethod paymentMethod) {
setFirstName(FirstName);
setLastName(LastName);
setCountry(Country);
setPhoneNumber(PhoneNumber);
setEmail(Email);
setPassword(Password);
setPaymentMethod(paymentMethod);
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
this.FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
this.LastName = lastName;
}
public String getCountry() {
return Country;
}
public void setCountry(String country) {
this.Country = country;
}
public String getPhoneNumber() {
return PhoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.PhoneNumber = phoneNumber;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
this.Email = email;
}
public String getPassword() {
return Password;
}
public void setPassword(String password) {
this.Password = password;
}
public PaymentMethod getPaymentMethod() {
return paymentMethod;
}
public void setPaymentMethod(PaymentMethod paymentMethod) {
this.paymentMethod = paymentMethod;
}
}
How I consume the unmarshal
List<T> accountInfo = (List<T>)ProcessClassHelper.unmarshal(xmlfile, Class.forName(Constants.ClassesDir +className));
I'm unsure what's causing the issue but the object is returned as single object even though there are multiple accounts and the returned data are null.
Thanks in advance.
Your Java classes don't match the structure of your XML file.
As @Rhayene already commented, you need separate Java classes for
AccountInfo and Account.
AccountInfo will contain only a list of Accounts:
@XmlRootElement(name = "AccountInfo")
@XmlAccessorType(XmlAccessType.FIELD)
public class AccountInfo {
@XmlElement(name = "Account")
private List<Account> accounts;
// + constructors, getters, setters
}
Account will contain all the properties which you had in in AccountInfo before.
(By the way: You should also follow the convention of field names beginning with lower-case letter. This will not break anything because the XML names are still specified by @XmlElement)
@XmlAccessorType(XmlAccessType.FIELD)
public class Account {
@XmlElement(name = "FirstName")
private String firstName;
@XmlElement(name = "LastName")
private String lastName;
@XmlElement(name = "Country")
private String country;
@XmlElement(name = "PhoneNumber")
private String phoneNumber;
@XmlElement(name = "Email")
private String email;
@XmlElement(name = "Password")
private String password;
@XmlElement(name = "PaymentMethod")
private PaymentMethod paymentMethod;
// + constructors, getters, setters
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With