Serialize Java List to XML using Jackson XML mapper - java

Hi I need to create an XML from JAVA using Jackson-dataformat XMLMapper.
The XML should be like
<Customer>
<id>1</id>
<name>Mighty Pulpo</name>
<addresses>
<city>austin</city>
<state>TX</state>
</addresses>
<addresses>
<city>Hong Kong</city>
<state>Hong Kong</state>
</addresses>
</Customer>
But I get it always like with an extra "< addresses> < /addresses>" tag.
<Customer>
<id>1</id>
<name>Mighty Pulpo</name>
<addresses>
<addresses>
<city>austin</city>
<state>TX</state>
</addresses>
<addresses>
<city>Hong Kong</city>
<state>Hong Kong</state>
</addresses>
<addresses>
</Customer>
I am using below code to create XML
JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
XmlMapper mapper = new XmlMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(jaxbAnnotationModule);
mapper.registerModule(new GuavaModule());
String xml = mapper.writeValueAsString(customer);
System.out.println(xml);
Please can some one help me? How can I remove the extra tag please. I have tried to use #XmlElement but it does not help help. TIA!!

Try the below code
#JacksonXmlRootElement(localName = "customer")
class Customer {
#JacksonXmlProperty(localName = "id")
private int id;
#JacksonXmlProperty(localName = "name")
private String name;
#JacksonXmlProperty(localName = "addresses")
#JacksonXmlElementWrapper(useWrapping = false)
private Address[] address;
// you can add it on getter method instead of declaration.
#JacksonXmlElementWrapper(useWrapping = false)
public Address[] getAddress(){
return address;
}
//getters, setters, toString
}
class Address {
#JacksonXmlProperty(localName = "city")
private String city;
#JacksonXmlProperty(localName = "state")
private String state;
// getter/setter
}

This setting changes default wrapping behavior, if you don't want to deal with annotation everywhere in your code.
XmlMapper mapper = new XmlMapper();
mapper.setDefaultUseWrapper(false);

Just to add to ManojP's answer, if adding the #JacksonXmlElementWrapper(useWrapping = false) on the declaration of your variable doesn't work (which was the case for me), adding it to the getter method will do the trick.

Related

unmarshal using jaxb having inner tag

I want to unmarshal my below xml file using JAXB.
<School>
<Student>
<Name> My xyz<Name>
<Hobbies> Playing Cricket <sup>+</sup> Watching TV</Hobbies>
</Student>
</School>
In Above example , There is one school with student which having hobbies.
Whenever i unmarshal above xml using (#XmlPath) i got only "Watching TV" but not "Playing Cricket".
I have tried to unmarshal using "DomHandler" also but not success.
Thanks.
I think your XML should be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<School>
<Student>
<Name>My xyz</Name>
<Hobbies>
<Name>Playing Cricket</Name>
<Hobby>
</Hobby>
<Name>Playing Cricket</Name>
</Hobbies>
</Student>
<!-- OTHER STUDENTS FOLLOW-->
</School>
and then the correspondant java object structure would be something like:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "School")
class School {
#XmlElement(required = true, name = "Student")
Student student;
}
#XmlAccessorType(XmlAccessType.FIELD)
class Hobby {
#XmlElement(required = true, name = "Name")
String name;
}
#XmlAccessorType(XmlAccessType.FIELD)
class Student {
#XmlElement(required = true, name = "Name")
String name;
#XmlElement(required = true, name = "Hobbies")
List<Hobby> hobbies;
}
I took off the getters and the setters for brevity.

JAXB: how to unmarshal a List of objects of different types inside a wrapper?

I'm stucked at parsing the following xml with JAXB:
<?xml version="1.0" encoding="utf-8"?>
<dashboardreport name="exampleDashboard" version="6.5.6.1013" reportdate="2016-12-16T11:05:19.329+01:00" description="">
<data>
<incidentchartdashlet name="Incident Chart" description="" />
<chartdashlet name="WebRequestTime" showabsolutevalues="false" />
<chartdashlet name="WebServiceTime" showabsolutevalues="false" />
</data>
</dashboardreport>
I used the following java classes to unmarshal the xml:
Dashboardreport.java
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "dashboardreport")
public class Dashboardreport {
#XmlElementWrapper(name = "data")
#XmlElement(name = "chartdashlet")
protected List<Chartdashlet> chartdashlets;
#XmlElementWrapper(name = "data")
#XmlElement(name = "incidentchartdashlet")
protected List<Incidentchartdashlet> incidentchartdashlets;
#XmlAttribute(name = "name")
protected String name;
}
I just want to unmarshal the xml without using a wrapper class around incidentchartdashlets and chartdashlet, cause both types differ a lot.
I only can use the XmlElementWrapper annotation once, so that only chartdashlets get filled and incidentchartdashlets is null.
Is there any solution with JAXB without using a seperate wrapper class?
I assume your dashlet classes are defined like
class Chartdashlet extends Dashlet and class Incidentchartdashlet extends Dashlet.
Then the preferred JAXB way to handle your mixed list of dashlets would be
by using the #XmlElements
annotation:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "dashboardreport")
public class Dashboardreport {
#XmlElementWrapper(name = "data")
#XmlElements({
#XmlElement(name = "chartdashlet", type = Chartdashlet.class),
#XmlElement(name = "incidentchartdashlet", type = Incidentchartdashlet.class)
})
protected List<Dashlet> dashlets;
#XmlAttribute(name = "name")
protected String name;
}

Multiple XML tag by JAXB

I'm using JAXB for generating XML, like this:
<Country>
<City>..</City>
<Adr>...</Adr>
</Country>
I have special class, which generate this XML:
#XmlElement(name = "Country")
private String country;
#XmlElement(name = "City")
private String city;
#XmlElement(name = "Adr")
private String adr;
with setters and getters, of course. But, how need I change this code, if I want to see XML like this?
<Country>
<City>..</City>
<Adr>...</Adr>
<City>..</City>
<Adr>...</Adr>
</Country>

Skip XML nodes while unmarshaling XML with JAXB

Is it possible to unmarshal a XML file like this:
<company id="bh23" name="imob">
<store>
<store-info id="2392">
<address>NYC</address>
<name>Imob's NYC 5th</name>
</store>
<products>
<product>
<name>keyboard</keyboard>
<price>2000</price>
</product>
<product>
<name>mouse</keyboard>
<price>1000</price>
</product>
</products>
</store>
<store />
</stores>
into classes like these:
#XmlElementRoot(name = "company")
public class Company {
#XmlAttribute (name = "id")
String id;
#XmlAttribute (name = "name")
String name;
#XmlElement (name = "store")
List<Store>stores;
//all the getters and setters
}
#XmlElementRoot (name = "store")
public class Store {
#XmlAttribute (name = "id")
String id;
#XmlElement (name = "address")
String address;
#XmlElement (name = "name")
String name;
#XmlElementWrapper (name = "products")
#XmlElement (name = "product")
List<Product>products;
//all the getters and setters
}
public class main {
public static void main (String args[]) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Company.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Company portfolio = (Company) jaxbUnmarshaller.unmarshal(new File(xmlUrlPath));
System.out.println(portfolio.toString());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
I'm trying to "skip" or "jump" the node named "store-info" because I don't want to create another class just to keep the store's address and name, since it would be more simple to "append" both address and name to "Store" class.
Of course, when I run the code, the vars "address", "id" and "name" becomes null and only the list of products is correctly unmarshaled.
Is there a way to skip a node, merging their fields into another class? I'm avoiding (for "legal" purposes) the use of MOXy lib and their XPath annotation.
You could create a StAX filtered XMLStreamReader and have JAXB unmarshal that to ignore one or more XML elements.
http://docs.oracle.com/javase/7/docs/api/javax/xml/stream/XMLInputFactory.html#createFilteredReader%28javax.xml.stream.XMLStreamReader,%20javax.xml.stream.StreamFilter%29
Below is a link to a full example I gave in an answer to a similar question:
JAXB filtered parsing

create nested structure using JAXB notations

<?xml version='1.0'?>
<info>
<contract>
<symbol>IBM</symbol>
<sectype>STK</sectype>
<exchange>SMART</exchange>
<currency>USD</currency>
</contract>
<order>
<action>SELL</action>
<quantity>100</quantity>
<ordertype>LMT</ordertype>
<imtprice>imtprice</imtprice>
<transmit>false</transmit>
</order>
</info>
I want to use jaxb annotations with existing java classes to create above XML input but i don't know how create nested xml structure based on Java classes
Try this:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(propOrder =
{"contract", "order"}) public class Info
{ #XmlElement(required =
true) private Contract
contract; #XmlElement(required = true) private Order order;
// Getters and setters }
Another class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(propOrder = {"symbol",
"sectype", "exchange",
"currency"}) public class
Contract { #XmlElement(required
= true) private String symbol; #XmlElement(required =
true) private String
sectype; #XmlElement(required =
true) private String
exchange; #XmlElement(required
= true) private String currency; //Getters and
setters}
Create an order class the same way.

Categories

Resources