Xml to Java Object using JAXB - java

I need converter this xml to Java Object, I was using a manual DOM w3c (DocumentBuilder).
But I would use the JAXB,
This is XML
<?xml version="1.0" encoding="UTF-8"?>
<user-agent>
<style-class>{prefix} {prefix}-{0}</style-class>
<template name="basic" default="true">/META-INF/page-basic.xhtml</template>
<template name="frame">/META-INF/page-frame.xhtml</template>
<support id="MSIE-OLD">
<pattern>.*MSIE (4|5|6|7|8).*</pattern>
<prefix>ie-old</prefix>
<template name="no-support" default="true">/META-INF/no-support.xhtml</template>
<style-class>no-support {prefix}</style-class>
</support>
<support id="MSIE">
<pattern>.*MSIE (\d+).*</pattern>
<prefix>ie</prefix>
</support>
<support id="Firefox">
<pattern>.*Firefox/(\d+).*</pattern>
<prefix>fx</prefix>
</support>
<support id="Android-Fx">
<pattern>.*Firefox/(\d+).*Android/(\d+).*</pattern>
<prefix>fx</prefix>
<template name="basic" default="true">/META-INF/movil-basic.xhtml</template>
<template name="frame">/META-INF/movil-frame.xhtml</template>
<style-class>fx fx-{0} android-{1}</style-class>
</support>
</user-agent>
This is my java class:
public class Support implements Serializable {
private final String id;
private final Pattern pattern;
private final String prefix;
private final Map<String, String> templates = new HashMap();
private final String defaultTemplate;
private final String styleClass;
}
Help me please, I dont know how to uses case for default attribute and default template, I try implement my SupportAdapter (extends XmlAdapter)

you have to create Jaxb pojos for it
1. UserAgent
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "styleClass", "template", "support" })
#XmlRootElement(name = "user-agent")
public class UserAgent {
#XmlElement(name = "style-class", required = true)
protected String styleClass;
#XmlElement(required = true)
protected List<Template> template;
#XmlElement(required = true)
protected List<Support> support;
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String value) {
this.styleClass = value;
}
public List<Template> getTemplate() {
if (template == null) {
template = new ArrayList<Template>();
}
return this.template;
}
public List<Support> getSupport() {
if (support == null) {
support = new ArrayList<Support>();
}
return this.support;
}
}
2. Support
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "pattern", "prefix", "template", "styleClass" })
#XmlRootElement(name = "support")
public class Support {
#XmlElement(required = true)
protected String pattern;
#XmlElement(required = true)
protected String prefix;
protected List<Template> template;
#XmlElement(name = "style-class")
protected String styleClass;
#XmlAttribute
protected String id;
public String getPattern() {
return pattern;
}
public void setPattern(String value) {
this.pattern = value;
}
public String getPrefix() {
return prefix;
}
public void setPrefix(String value) {
this.prefix = value;
}
public List<Template> getTemplate() {
if (template == null) {
template = new ArrayList<Template>();
}
return this.template;
}
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String value) {
this.styleClass = value;
}
public String getId() {
return id;
}
public void setId(String value) {
this.id = value;
}
}
3. Template
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlValue;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = { "content" })
#XmlRootElement(name = "template")
public class Template {
#XmlValue
protected String content;
#XmlAttribute(name = "default")
protected String _default;
#XmlAttribute
protected String name;
public String getContent() {
return content;
}
public void setContent(String value) {
this.content = value;
}
public String getDefault() {
return _default;
}
public void setDefault(String value) {
this._default = value;
}
public String getName() {
return name;
}
public void setName(String value) {
this.name = value;
}
}
4. finally Parse it
JAXBContext jaxbContext = JAXBContext.newInstance(UserAgent.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
// pase file, url , inputstream , string whatever you have.
UserAgent userAgent = (UserAgent) jaxbUnmarshaller.unmarshal(file);
//getting <template> data from last <support> tag
List<Template> templates = userAgent.getSupport().get(3).getTemplate();
for (Template template : templates) {
String wantToSeeTempalteData = String.format(
"Tempalt [name:%s , default:%s content:%s ]",
new Object[] { template.getName(),template.getDefault(), template.getContent() });
System.out.println(wantToSeeTempalteData);
}
Result
Tempalt [name:basic , default:true content:/META-INF/movil-basic.xhtml ]
Tempalt [name:frame , default:null content:/META-INF/movil-frame.xhtml ]

You can start with this example by creating two classes Support and MyTemplate
import java.io.Serializable;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.FIELD)
public class Support implements Serializable {
#XmlAttribute
private String id;
#XmlElement
private String pattern;
#XmlElement
private String prefix;
#XmlElement(name = "style-class")
private String styleClass;
#XmlElement(name = "template")
private List<MyTemplate> templateList;
}
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
public class MyTemplate implements Serializable{
#XmlAttribute
private String name;
#XmlAttribute(name = "default")
private String defaultValue;
#XmlValue
private String value;
public MyTemplate() {
super();
}
}

Use frameworks like XmlBeans http://xmlbeans.apache.org/
This would do the data conversion from xml to Java and vice versa.

Related

Unmarshal the List Object Created in POJO classes

I created one Object class which will be my root element and in that I have two attributes and one element shown below:
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Object {
private String id;
private String type;
List <UniqueId> UniqueId;
public List<UniqueId> getUniqueId() {
return UniqueId;
}
public void setUniqueId(List<UniqueId> uniqueId) {
UniqueId = uniqueId;
}
#XmlAttribute
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlAttribute
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Object() {
super();
}
public Object(String id, String type, List<classes.UniqueId> uniqueId) {
super();
this.id = id;
this.type = type;
UniqueId = uniqueId;
}
}
and then one class for List <UniqueId> UniqueId;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class UniqueId {
private String Uid;
public String getUid() {
return Uid;
}
public void setUid(String uid) {
Uid = uid;
}
public UniqueId(String uid) {
super();
Uid = uid;
}
public UniqueId() {
super();
}
}
and in the main class, I want to Unmarshal the UniqueId data from VPMobject and I'm getting null value there. How can I fetch the uniqueId if there are n UId's present in the xml file?
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import pojoClasses.VPMObject;
public class MarshalEAD {
public static void main(String[] args) {
try {
File f1 = new File("src\\xmlData\\Test1.xml");
JAXBContext contextObj = JAXBContext.newInstance(Assembly.class);
Unmarshaller unmarshal = contextObj.createUnmarshaller();
// add information or objects to be fetched and written as output
Assembly AD= (Assembly)unmarshal.unmarshal(f1);
System.out.println("Extracted Xml File Information:\n\t");
System.out.println("Root Element: ");
List<VPMObject> list = AD.getVPMObject();
for(VPMObject fetch:list) {
System.out.println("ID: " + fetch.getId());
System.out.println("Type: " + fetch.getType());
System.out.println("UniqueId: " + fetch.getUniqueId() );
}
}
catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
}
}

Get elements as list

I have this JAXB component which I would like to get as a list:
#XmlRootElement(name = "payment")
#XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
#XmlElement(name = "transaction_types")
public TransactionTypes transactionTypes;
}
public class TransactionTypes {
#XmlElement(name = "transaction_type")
public String transaction_type;
#XmlAttribute
public String name;
public String getTransaction_type() {
return transaction_type;
}
public void setTransaction_type(String transaction_type) {
this.transaction_type = transaction_type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
XML structure:
<payment>
<transaction_types>
<transaction_type name="type1"/>
<transaction_type name="type2"/>
<transaction_type name="type3"/>
</transaction_types>
</payment>
The question is how I can get all transaction types as a list?
Can you give me some idea how should I modify the JAXB Object?
EDIT:
I tried this
#XmlRootElement(name = "payment")
#XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
#XmlElementWrapper(name = "transaction_types")
public List<TransactionTypes> transactionTypes;
}
Inner object which will hold the list:
public class TransactionTypes {
#XmlElement(name = "transaction_type")
public String transaction_type;
#XmlAttribute
public String name;
public String getTransaction_type() {
return transaction_type;
}
public void setTransaction_type(String transaction_type) {
this.transaction_type = transaction_type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
To get all the transaction_type as a list, I have somewhat modified your code. I have introduced a new class TransactionList which will contain the list of transaction_type
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "payment")
#XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
#XmlElement(name = "transaction_types")
public TransactionList transactionList;
public Transaction() {
super();
}
#Override
public String toString() {
return "Transaction [TransactionList=" + transactionList + "]";
}
}
TransactionList class
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.FIELD)
public class TransactionList {
#XmlElement(name = "transaction_type")
public List<TransactionType> transactionType;
public TransactionList(List<TransactionType> transactionTypes) {
transactionType = transactionTypes;
}
public TransactionList() {
super();
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (TransactionType transactionType : transactionType) {
sb.append(transactionType + "\n");
}
return sb.toString();
}
}
TransactionType class
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.FIELD)
public class TransactionType {
#XmlElement(name = "transaction_type")
private String transaction_type;
#XmlAttribute
private String name;
public TransactionType(String transaction_type, String name) {
this.transaction_type = transaction_type;
this.name = name;
}
public TransactionType() {
}
public String getTransaction_type() {
return transaction_type;
}
public void setTransaction_type(String transaction_type) {
this.transaction_type = transaction_type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "TransactionTypes [transaction_type=" + transaction_type + ", name=" + name + "]";
}
}
main method
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Transaction.class);
Unmarshaller um = context.createUnmarshaller();
Transaction transaction = (Transaction) um.unmarshal(new FileReader(FILE));
System.out.println(transaction);
}
You can also check the output by directly changing the variable transactionType to List in Transaction table and assigning XMLElementWrapper annotation to it
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "payment")
#XmlAccessorType(XmlAccessType.FIELD)
public class Transaction {
#XmlElementWrapper(name = "transaction_types")
public List<TransactionType> transactionType;
public Transaction() {
}
}

Java Object to xml schema custom mapping - Web Service

I have a Web Service in JAX-WS and the maven goal('ws-jwsc') in pom.xml generates the WSDL file along with the input and output XSD.
I want to change the mapping of java class' attributes to WSDL/XSD schema in a different manner, as shown below:
I have two classes 1) Customer 2) Location
1. Customer - Customer specific info
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
public Customer() {
super();
}
public Customer(CustomerType customerType) {
this.customerType = customerType;
}
public enum CustomerType {
B, S, C
}
private CustomerType customerType;
private String name;
private Long accountNumber;
private Location location;
// getter/setter for properties
}
2. Location - Location object to contain addr1/addr2/city/state/zip/country
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Location {
private String address1;
private String address2;
private String city;
private String state;
private String zip;
private String country;
/**
* #return the city
*/`enter code here`
public String getCity() {
return city;
}
//getter/setter for properties
}
Now My question is at runtime there can be 3 values('B','C','S') of 'customerType' attribute in Customer class
So,
For example if the runTime value of customerType is 'S'.
then the code shall generate the Location object properties as 'ShipperAddress1', 'ShipperAddress2', 'ShipperCity', 'ShipperState', 'ShipperZip', 'ShipperCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country'properties respectively in the SOAP response XML.
example2: if the runTime value of customerType is 'C'.
then the code shall generate the Location object properties as 'ConsigneeAddress1', 'ConsigneeAddress2', 'ConsigneeCity', 'ConsigneeState', 'ConsigneeZip', 'ConsigneeCountry' for 'address1' , 'address2', 'city', 'state', 'zip' and 'country' properties respectively in the SOAP response XML.
I need to know whether it is possible to do that, If yes then How?
All the help is greatly appreciated.
You can very well do it, usning #XmlElementRef and then using "inheritence of Location.
Have a base class for Location, or AbstractLocation, and then "create" instance of Location for Customer Type shipper or consignee and Override the element name in child classes. I have an example below to demonstrate where I am showing it for one field Address1. You can overrride all required fields similarly.
Note that instead of having a Field Access type, I have made it Property so that we override only methods and fields remain "private" in base class. You can adapt that also, if you think field can be protected..
Example
In example I have just used LocationC and LocationS. You can add LocationB.
Customer.java with main class. Note #XmlElementRef(name = "Location")
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
public CustomerType getCustomerType() {
return customerType;
}
public void setCustomerType(CustomerType customerType) {
this.customerType = customerType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAccountNumber() {
return accountNumber;
}
public void setAccountNumber(Long accountNumber) {
this.accountNumber = accountNumber;
}
public GeneralLocation getLocation() {
return location;
}
public void setLocation(GeneralLocation location) {
this.location = location;
}
public Customer() {
super();
}
public Customer(CustomerType customerType) {
this.customerType = customerType;
}
public enum CustomerType {
B, S, C
}
private CustomerType customerType;
private String name;
private Long accountNumber;
#XmlElementRef(name = "Location")
private GeneralLocation location;
public static void main(String[] args) throws Exception {
Customer c = new Customer();
c.setAccountNumber(1111111l);
c.setCustomerType(CustomerType.C);
LocationC loc = new LocationC();
loc.setAddress1("I am address 1");
c.setLocation(loc);
Customer c2 = new Customer();
c2.setAccountNumber(222222l);
c.setCustomerType(CustomerType.S);
LocationS locs = new LocationS();
locs.setAddress1("I am S address 1");
c2.setLocation(locs);
JAXBContext jc = JAXBContext.newInstance(Customer.class);
Marshaller marrshaller = jc.createMarshaller();
marrshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marrshaller.marshal(c, System.out);
marrshaller.marshal(c2, System.out);
}
}
Base AbstractLocation.java (I have hidden it's property using annotation #XmlTransient.
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
#XmlRootElement
#XmlAccessorType(XmlAccessType.PROPERTY)
#XmlSeeAlso({LocationC.class, LocationS.class})
abstract class GeneralLocation {
private String address1;
private String address2;
private String city;
private String state;
private String zip;
private String country;
#XmlTransient()
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
LocationC.java
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement()
public class LocationC extends GeneralLocation {
#XmlElement(name="ConsigneeAddress1")
#Override
public String getAddress1() {
return super.getAddress1();
}
}
LocationS.java
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement()
#XmlAccessorType(XmlAccessType.PROPERTY)
public class LocationS extends GeneralLocation {
#XmlElement(name="ShipperAddress1")
public String getAddress1() {
return super.getAddress1();
}
}

Not able to extract only selected Tag values using Jaxb in Java

I've a very big XML string. Im posting here only part of the XML object. I'm trying to convert this XML to Java object. My first question is, should I need to create Java object of total XML tag values or can I have create the Java object of only selected inner XML objects? Please find my XML string.
<DATAPACKET REQUEST-ID = "2">
<HEADER>
<RESPONSE-TYPE CODE="1" DESCRIPTION="Response DataPacket"/>
<SEARCH-RESULT-LIST>
<SEARCH-RESULT-ITEM>
<NAME MATCHED="TRUE"/>
</SEARCH-RESULT-ITEM>
</SEARCH-RESULT-LIST>
</HEADER>
<BODY>
<CONS_SCORE>
<SCORE>0</SCORE>
<REASON1>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON1>
<REASON2>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON2>
<REASON3>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON3>
<REASON4>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON4>
</CONS_SCORE>
<CONSUMER_PROFILE2>
<CONSUMER_DETAILS2>
<RUID>1234</RUID>
<NAME>ABC</NAME>
<DATE_OF_BIRTH>1980-03-03T00:00:00+03:00</DATE_OF_BIRTH>
<GENDER>001</GENDER>
</CONSUMER_DETAILS2>
<ID_DETAILS2>
<SLNO>1</SLNO>
<SOURCE_ID>001</SOURCE_ID>
<ID_VALUE>2806</ID_VALUE>
<EXP_DATE>2018-07-13T00:00:00+03:00</EXP_DATE>
</ID_DETAILS2>
</CONSUMER_PROFILE2>
</BODY>
</DATAPACKET>
In the above object, I want to fetch only CONSUMER_PROFILE2 object. Here is my Dto class
#XmlRootElement(name = "DATAPACKET")
public class ConsumerProfileDto {
private ConsumerDetailsDto CONSUMER_DETAILS2;
private IdDetailsDto ID_DETAILS2;
public ConsumerDetailsDto getCONSUMER_DETAILS2() {
return CONSUMER_DETAILS2;
}
public void setCONSUMER_DETAILS2(ConsumerDetailsDto cONSUMER_DETAILS2) {
CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
}
public IdDetailsDto getID_DETAILS2() {
return ID_DETAILS2;
}
public void setID_DETAILS2(IdDetailsDto iD_DETAILS2) {
ID_DETAILS2 = iD_DETAILS2;
}
}
CONSUMER_DETAILS2 class
#XmlRootElement(name = "CONSUMER_DETAILS2")
public class ConsumerDetailsDto {
private String NAME;
private String DATE_OF_BIRTH;
private String GENDER;
private String NATIONALITY;
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
public String getDATE_OF_BIRTH() {
return DATE_OF_BIRTH;
}
public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
DATE_OF_BIRTH = dATE_OF_BIRTH;
}
public String getGENDER() {
return GENDER;
}
public void setGENDER(String gENDER) {
GENDER = gENDER;
}
public String getNATIONALITY() {
return NATIONALITY;
}
public void setNATIONALITY(String nATIONALITY) {
NATIONALITY = nATIONALITY;
}
Here is the code of unmarshalling
JAXBContext jaxbContext = JAXBContext.newInstance(ConsumerProfileDto.class);
StringReader reader = new StringReader(responseXML);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ConsumerDetailsDto que= (ConsumerDetailsDto) jaxbUnmarshaller.unmarshal(reader);
System.out.println(que.getDATE_OF_BIRTH());
System.out.println(que.getGENDER());;
System.out.println(que.getNAME());
P.S
I've used DocumentBuilder and I'm able to fetch the values using it. But, I want to extract using Jaxb.
You can't annotate as #XmlRootElement the Java class mirroring the XML element that you're interested on. You have to mirror in Java all the XML elements from the topmost element in the XML file (DATAPACKET) to the lowest ones (CONSUMER_DETAILS2 and ID_DETAILS2) in the path that you're interested, even if you're only interested in some of them.
I assume that the operator isn't interested in RUID (because the class CONSUMER_DETAILS2 doesn't include a field for this XML element), and also that the field NATIONALITY is not going to be loaded from this XML.
If the input XML of the question were in a file named input2.xml, then I'd have the following Java classes:
DataPacket
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "DATAPACKET")
public class DataPacket {
#XmlAttribute(name = "REQUEST_ID")
private int REQUEST_ID;
#XmlElement(name ="BODY")
private Body BODY;
public DataPacket(){}
public int getREQUEST_ID() {
return REQUEST_ID;
}
public void setREQUEST_ID(int REQUEST_ID) {
this.REQUEST_ID = REQUEST_ID;
}
public Body getBODY() {
return BODY;
}
public void setBODY(Body BODY) {
this.BODY = BODY;
}
}
Body
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class Body {
#XmlElement(name = "CONSUMER_PROFILE2")
private ConsumerProfile profile;
public Body(){}
public ConsumerProfile getProfile() {
return profile;
}
public void setProfile(ConsumerProfile profile) {
this.profile = profile;
}
}
ConsumerProfile
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
public class ConsumerProfile {
#XmlElement(name = "CONSUMER_DETAILS2")
private ConsumerDetails CONSUMER_DETAILS2;
#XmlElement(name = "ID_DETAILS2")
private IdDetails ID_DETAILS2;
public ConsumerProfile(){}
public ConsumerDetails getCONSUMER_DETAILS2() {
return CONSUMER_DETAILS2;
}
public void setCONSUMER_DETAILS2(ConsumerDetails cONSUMER_DETAILS2) {
CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
}
public IdDetails getID_DETAILS2() {
return ID_DETAILS2;
}
public void setID_DETAILS2(IdDetails iD_DETAILS2) {
ID_DETAILS2 = iD_DETAILS2;
}
}
ConsumerDetails
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class ConsumerDetails {
#XmlElement(name="NAME")
private String NAME;
#XmlElement(name="DATE_OF_BIRTH")
private String DATE_OF_BIRTH;
#XmlElement(name="GENDER")
private String GENDER;
private String NATIONALITY;
public ConsumerDetails(){}
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
public String getDATE_OF_BIRTH() {
return DATE_OF_BIRTH;
}
public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
DATE_OF_BIRTH = dATE_OF_BIRTH;
}
public String getGENDER() {
return GENDER;
}
public void setGENDER(String gENDER) {
GENDER = gENDER;
}
public String getNATIONALITY() {
return NATIONALITY;
}
public void setNATIONALITY(String nATIONALITY) {
NATIONALITY = nATIONALITY;
}
}
IdDetails
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class IdDetails {
#XmlElement(name="SLNO")
private int SLNO;
#XmlElement(name="SOURCE_ID")
private String SOURCE_ID;
#XmlElement(name="ID_VALUE")
private int ID_VALUE;
#XmlElement(name="EXP_DATE")
private String EXP_DATE;
public IdDetails(){}
public int getSLNO() {
return SLNO;
}
public void setSLNO(int SLNO) {
this.SLNO = SLNO;
}
public String getSOURCE_ID() {
return SOURCE_ID;
}
public void setSOURCE_ID(String SOURCE_ID) {
this.SOURCE_ID = SOURCE_ID;
}
public int getID_VALUE() {
return ID_VALUE;
}
public void setID_VALUE(int ID_VALUE) {
this.ID_VALUE = ID_VALUE;
}
public String getEXP_DATE() {
return EXP_DATE;
}
public void setEXP_DATE(String EXP_DATE) {
this.EXP_DATE = EXP_DATE;
}
}
Also, inside the same "test" package the jaxb.index file with:
DataPacket
ConsumerProfile
ConsumerDetails
IdDetails
Then, when testing with this Test class:
package test;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class Test {
public static void main(String[] args) {
try{
JAXBContext jc = JAXBContext.newInstance(DataPacket.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input2.xml");
DataPacket dp = (DataPacket) unmarshaller.unmarshal(xml);
Body body = dp.getBODY();
ConsumerProfile profile = body.getProfile();
ConsumerDetails consumerDetail = profile.getCONSUMER_DETAILS2();
IdDetails idDetails = profile.getID_DETAILS2();
System.out.println("ConsumerDetails name:"+consumerDetail.getNAME()+
" date of birth:"+consumerDetail.getDATE_OF_BIRTH()+
" gender:"+consumerDetail.getGENDER()+
"IdDetails SLNO:"+idDetails.getSLNO()+
" SOURCE_ID:"+idDetails.getSOURCE_ID()+
" ID_VALUE:"+idDetails.getID_VALUE()+
" EXP_DATE:"+idDetails.getEXP_DATE());
}
catch(JAXBException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}

Not able to unmarshall child object using jaxb [duplicate]

I've a very big XML string. Im posting here only part of the XML object. I'm trying to convert this XML to Java object. My first question is, should I need to create Java object of total XML tag values or can I have create the Java object of only selected inner XML objects? Please find my XML string.
<DATAPACKET REQUEST-ID = "2">
<HEADER>
<RESPONSE-TYPE CODE="1" DESCRIPTION="Response DataPacket"/>
<SEARCH-RESULT-LIST>
<SEARCH-RESULT-ITEM>
<NAME MATCHED="TRUE"/>
</SEARCH-RESULT-ITEM>
</SEARCH-RESULT-LIST>
</HEADER>
<BODY>
<CONS_SCORE>
<SCORE>0</SCORE>
<REASON1>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON1>
<REASON2>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON2>
<REASON3>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON3>
<REASON4>
<HEADER></HEADER>
<DESCRIPTION></DESCRIPTION>
</REASON4>
</CONS_SCORE>
<CONSUMER_PROFILE2>
<CONSUMER_DETAILS2>
<RUID>1234</RUID>
<NAME>ABC</NAME>
<DATE_OF_BIRTH>1980-03-03T00:00:00+03:00</DATE_OF_BIRTH>
<GENDER>001</GENDER>
</CONSUMER_DETAILS2>
<ID_DETAILS2>
<SLNO>1</SLNO>
<SOURCE_ID>001</SOURCE_ID>
<ID_VALUE>2806</ID_VALUE>
<EXP_DATE>2018-07-13T00:00:00+03:00</EXP_DATE>
</ID_DETAILS2>
</CONSUMER_PROFILE2>
</BODY>
</DATAPACKET>
In the above object, I want to fetch only CONSUMER_PROFILE2 object. Here is my Dto class
#XmlRootElement(name = "DATAPACKET")
public class ConsumerProfileDto {
private ConsumerDetailsDto CONSUMER_DETAILS2;
private IdDetailsDto ID_DETAILS2;
public ConsumerDetailsDto getCONSUMER_DETAILS2() {
return CONSUMER_DETAILS2;
}
public void setCONSUMER_DETAILS2(ConsumerDetailsDto cONSUMER_DETAILS2) {
CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
}
public IdDetailsDto getID_DETAILS2() {
return ID_DETAILS2;
}
public void setID_DETAILS2(IdDetailsDto iD_DETAILS2) {
ID_DETAILS2 = iD_DETAILS2;
}
}
CONSUMER_DETAILS2 class
#XmlRootElement(name = "CONSUMER_DETAILS2")
public class ConsumerDetailsDto {
private String NAME;
private String DATE_OF_BIRTH;
private String GENDER;
private String NATIONALITY;
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
public String getDATE_OF_BIRTH() {
return DATE_OF_BIRTH;
}
public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
DATE_OF_BIRTH = dATE_OF_BIRTH;
}
public String getGENDER() {
return GENDER;
}
public void setGENDER(String gENDER) {
GENDER = gENDER;
}
public String getNATIONALITY() {
return NATIONALITY;
}
public void setNATIONALITY(String nATIONALITY) {
NATIONALITY = nATIONALITY;
}
Here is the code of unmarshalling
JAXBContext jaxbContext = JAXBContext.newInstance(ConsumerProfileDto.class);
StringReader reader = new StringReader(responseXML);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ConsumerDetailsDto que= (ConsumerDetailsDto) jaxbUnmarshaller.unmarshal(reader);
System.out.println(que.getDATE_OF_BIRTH());
System.out.println(que.getGENDER());;
System.out.println(que.getNAME());
P.S
I've used DocumentBuilder and I'm able to fetch the values using it. But, I want to extract using Jaxb.
You can't annotate as #XmlRootElement the Java class mirroring the XML element that you're interested on. You have to mirror in Java all the XML elements from the topmost element in the XML file (DATAPACKET) to the lowest ones (CONSUMER_DETAILS2 and ID_DETAILS2) in the path that you're interested, even if you're only interested in some of them.
I assume that the operator isn't interested in RUID (because the class CONSUMER_DETAILS2 doesn't include a field for this XML element), and also that the field NATIONALITY is not going to be loaded from this XML.
If the input XML of the question were in a file named input2.xml, then I'd have the following Java classes:
DataPacket
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "DATAPACKET")
public class DataPacket {
#XmlAttribute(name = "REQUEST_ID")
private int REQUEST_ID;
#XmlElement(name ="BODY")
private Body BODY;
public DataPacket(){}
public int getREQUEST_ID() {
return REQUEST_ID;
}
public void setREQUEST_ID(int REQUEST_ID) {
this.REQUEST_ID = REQUEST_ID;
}
public Body getBODY() {
return BODY;
}
public void setBODY(Body BODY) {
this.BODY = BODY;
}
}
Body
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class Body {
#XmlElement(name = "CONSUMER_PROFILE2")
private ConsumerProfile profile;
public Body(){}
public ConsumerProfile getProfile() {
return profile;
}
public void setProfile(ConsumerProfile profile) {
this.profile = profile;
}
}
ConsumerProfile
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
public class ConsumerProfile {
#XmlElement(name = "CONSUMER_DETAILS2")
private ConsumerDetails CONSUMER_DETAILS2;
#XmlElement(name = "ID_DETAILS2")
private IdDetails ID_DETAILS2;
public ConsumerProfile(){}
public ConsumerDetails getCONSUMER_DETAILS2() {
return CONSUMER_DETAILS2;
}
public void setCONSUMER_DETAILS2(ConsumerDetails cONSUMER_DETAILS2) {
CONSUMER_DETAILS2 = cONSUMER_DETAILS2;
}
public IdDetails getID_DETAILS2() {
return ID_DETAILS2;
}
public void setID_DETAILS2(IdDetails iD_DETAILS2) {
ID_DETAILS2 = iD_DETAILS2;
}
}
ConsumerDetails
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class ConsumerDetails {
#XmlElement(name="NAME")
private String NAME;
#XmlElement(name="DATE_OF_BIRTH")
private String DATE_OF_BIRTH;
#XmlElement(name="GENDER")
private String GENDER;
private String NATIONALITY;
public ConsumerDetails(){}
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
public String getDATE_OF_BIRTH() {
return DATE_OF_BIRTH;
}
public void setDATE_OF_BIRTH(String dATE_OF_BIRTH) {
DATE_OF_BIRTH = dATE_OF_BIRTH;
}
public String getGENDER() {
return GENDER;
}
public void setGENDER(String gENDER) {
GENDER = gENDER;
}
public String getNATIONALITY() {
return NATIONALITY;
}
public void setNATIONALITY(String nATIONALITY) {
NATIONALITY = nATIONALITY;
}
}
IdDetails
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
#XmlAccessorType(XmlAccessType.NONE)
class IdDetails {
#XmlElement(name="SLNO")
private int SLNO;
#XmlElement(name="SOURCE_ID")
private String SOURCE_ID;
#XmlElement(name="ID_VALUE")
private int ID_VALUE;
#XmlElement(name="EXP_DATE")
private String EXP_DATE;
public IdDetails(){}
public int getSLNO() {
return SLNO;
}
public void setSLNO(int SLNO) {
this.SLNO = SLNO;
}
public String getSOURCE_ID() {
return SOURCE_ID;
}
public void setSOURCE_ID(String SOURCE_ID) {
this.SOURCE_ID = SOURCE_ID;
}
public int getID_VALUE() {
return ID_VALUE;
}
public void setID_VALUE(int ID_VALUE) {
this.ID_VALUE = ID_VALUE;
}
public String getEXP_DATE() {
return EXP_DATE;
}
public void setEXP_DATE(String EXP_DATE) {
this.EXP_DATE = EXP_DATE;
}
}
Also, inside the same "test" package the jaxb.index file with:
DataPacket
ConsumerProfile
ConsumerDetails
IdDetails
Then, when testing with this Test class:
package test;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class Test {
public static void main(String[] args) {
try{
JAXBContext jc = JAXBContext.newInstance(DataPacket.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("input2.xml");
DataPacket dp = (DataPacket) unmarshaller.unmarshal(xml);
Body body = dp.getBODY();
ConsumerProfile profile = body.getProfile();
ConsumerDetails consumerDetail = profile.getCONSUMER_DETAILS2();
IdDetails idDetails = profile.getID_DETAILS2();
System.out.println("ConsumerDetails name:"+consumerDetail.getNAME()+
" date of birth:"+consumerDetail.getDATE_OF_BIRTH()+
" gender:"+consumerDetail.getGENDER()+
"IdDetails SLNO:"+idDetails.getSLNO()+
" SOURCE_ID:"+idDetails.getSOURCE_ID()+
" ID_VALUE:"+idDetails.getID_VALUE()+
" EXP_DATE:"+idDetails.getEXP_DATE());
}
catch(JAXBException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}

Categories