Retrofit with Simpleframework XML - java

I'm using retrofit to connect to my API and trying to parse messages with Simpleframework XML, but I keep getting the error below:
retrofit.RetrofitError: org.simpleframework.xml.core.ElementException: Element 'head' does not have a match in class Classes at line 5
Here are my classes and XML that I should be getting but Im connecting to an Microsoft asmx service and its returning the html above http://pastebin.com/ASvV0Cwq, somewhere in the soap envelope should be the xml body
#Root(name = "tables")
public class Classes
{
#ElementList(name = "tables", inline = true)
List<MyClass> tables;
}
:
Root(name="table")
public class MyClass implements Serializable
{
#Element(name = "id")
private String id;
#Element(name = "name")
private String name;
#Element(name = "value")
private String value;
#Element(name = "key")
private String key;
}
This should be the XML:
<?xml version="1.0" encoding="UTF-8"?>
<tables>
<table>
<id>1</id>
<name>Admin</name>
<value>111</value>
<key>999</key>
</table>
<table>
<id>5</id>
<name>Bari Limani</name>
<value>121</value>
<key>999</key>
</tables>

An end table tag is missing in the XML.

Related

Deserializing XML with nested fields to a single JavaObject

My goal is to convert the XML to JavaObject and have the JavaObject be able to handle one or more "Tasks".
I would also like to be able to convert the JavaObject to JSON as well.
How can this be done? At it's current state, I am able to convert if only one task exists, anymore results in an error.
I have an XML file that follows this structure:
<Plan>
<ID></ID>
<Comment></Comment>
<CreateTime></CreateTime>
<Task>...</Task>
<Task>...</Task>
<Task>...</Task>
</Plan>
Each Task element is structured like so:
<Task>
<Type></Type>
<Time></Time>
<Target>
<Code></Code>
<TargetId></TargetId>
<Content>
<Stuff1></Stuff1>
<Stuff2></Stuff2>
<Stuff3></Stuff3>
</Content>
</Target>
</Task>
I am able to deserialize the XML when there is only one Task involved. Anymore gives me errors.
My Classes (simplified) are as follows:
#Root(name = "Plan")
public class Plan{
#Element(name = "ID")
private String id;
#Element(name = "Comment")
private String comment;
#Element(name = "CreateTime")
private String createTime;
#Element(name = "Task")
private Task task;
}
#Root(name = "Task")
public class Task{
#Element(name = "Type")
private String type;
#Element(name = "Time")
private String time;
#Element(name = "Target")
private Target target;
}
#Root(name = "Target")
public class Target{
#Element(name = "Code")
private String code;
#Element(name = "TargetId")
private String targetId;
#Element(name = "Content")
private Content content;
}
#Root(name = "Content")
public class Content{
#Element(name = "Stuff1")
private String stuff1;
#Element(name = "Stuff2")
private String stuff2;
#Element(name = "Stuff3")
private String stuff3;
}
In the schema file, I set this but doesn't seem to work:
<xs:element name="Task" type="Task" minOccurs="1" maxOccurs="unbounded">
At it's current state, I am able to convert if only one task exists,
anymore results in an error.
This happens because your element annotation interprets the task tag as a property, so if there is more than one it raises an error. To avoid this behaviour you can use the JacksonXmlElementWrapper annotation you can apply to your task list:
public class Plan {
#JacksonXmlProperty(localName = "Task")
#JacksonXmlElementWrapper(useWrapping = false)
List<Task> tasks;
}
public class Task {}
This above is a starting basic example you can use to define more complicated xmls.

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

Parsing optional nested XML Elements via JAXB

I have XML input that could basically look like this:
<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<object label="" Property1="43" id="2">
<mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="196" y="161" width="200" height="30" as="geometry"/>
</mxCell>
</object>
<object label="" Property2="Helloooo" id="3">
<mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="192" y="269" width="200" height="30" as="geometry"/>
</mxCell>
</object>
<object label="" Property3="23" id="4">
<mxCell style="whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="210" y="383" width="200" height="30" as="geometry"/>
</mxCell>
</object>
</root>
</mxGraphModel>
I'm trying to parse this input via JAXB:
MxGraphModel.java:
#XmlRootElement(name = "mxGraphModel")
#XmlAccessorType(XmlAccessType.FIELD)
public class MxGraphModel {
#XmlElementWrapper(name = "root")
#XmlElement(name = "object")
private ArrayList<MxObject> mxObjects;
#XmlElement(name = "mxCell")
private ArrayList<MxCell> mxCells;
//getters and setters...
}
MxObject.java:
#XmlAccessorType(XmlAccessType.FIELD)
public class MxObject {
#XmlAttribute
private String id;
#XmlAttribute
private String label;
#XmlAttribute
private String documentName;
#XmlAttribute
private String documentDescription;
#XmlElement
private MxCell mxCell;
//getters and setters...
}
MxCell.java:
#XmlAccessorType(XmlAccessType.FIELD)
public class MxCell {
#XmlAttribute
private String id;
#XmlAttribute
private String parent;
#XmlAttribute
private String value;
#XmlAttribute
private String style;
#XmlAttribute
private String vertex;
#XmlElement(name = "mxGeometry")
private MxGeometry geometry;
//getters and setters...
}
DemoController.java:
#RestController
#RequestMapping("/xml")
public class DemoController {
#RequestMapping(method = RequestMethod.POST, consumes = {MediaType.APPLICATION_XML_VALUE})
public void parseXML(#RequestBody MxGraphModel mxGraphModel) {
//mxGraphModel contains EITHER objects of type MxObject
//OR
//MxCell
}
}
My problem is, that the parsing operation results in an MxGraphModel object that contains either a collection of objects OR a collection of mxCells - but never both.
It seems to me that the order in which I declare the XmlElements ("object" and "mxCell") is relevant for the parsing result. When I declare mxCell before object, 2 mxCells are being parsed (which is correct), but the object collection remains null. And the other way around.
Is it possible to have both XmlElements parsed? I don't know whether the issue is related to the fact that an object element could contain an mxCell element itself...
Thanks.
#Dimpre Jean-Sébastien:
You're totally right, sorry for posting the answer this late.
The solution is not to use the root ElementWrapper
So instead of using
#XmlElementWrapper(name = "root")
I had to create a root XmlElement in MxGraphModel.java:
#XmlElement(name = "root")
private MxRoot mxRoot;
Furthermore I created a file called MxRoot.java and moved all collections inside it:
MxRoot.java:
#XmlAccessorType(XmlAccessType.FIELD)
public class MxRoot {
#XmlElement(name = "UserObject")
private ArrayList<MxObject> mxUserObjects;
#XmlElement(name = "object")
private ArrayList<MxObject> mxObjects;
//XmlElement sets the name of the entities
#XmlElement(name = "mxCell")
private ArrayList<MxCell> mxCells;
//getters and setters...
}
It seems the #XmlWrapper Annotation expects exactly one collection. It is not meant to wrap around multiple collections (makes sense now that I know it :))
Thanks to all!

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>

How to generate xml tag as full class name using jaxb?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<batch-execution>
<insert out-identifier="employee" return-object="true" entry-point="DEFAULT">
<fact xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="employee">
<name>Rajashekhar</name>
<age>21</age>
</fact>
</insert>
<fire-all-rules></fire-all-rules>
</batch-execution>
Now I am getting this output as above but I want out put like below
<batch-execution>
<insert out-identifier="employee" return-object="true"
entry-point="DEFAULT">
<com.practise.Employee>
<name>Rajashekhar</name>
<age>21</age>
</com.practise.Employee>
</insert>
<fire-all-rules />
</batch-execution>
My Jaxb classes are
Request.java
#XmlRootElement(name = "batch-execution")
#XmlAccessorType(XmlAccessType.FIELD)
public class Request implements Serializable {
#XmlElement(name = "insert")
private List<Insert> insert;
#XmlElement(name = "fire-all-rules",nillable=true)
private String fireAllRules = "";
.
..
setters and getter
Insert.java
#XmlAccessorType(XmlAccessType.FIELD)
public class Insert {
#XmlAttribute(name = "out-identifier", required = true)
private String outIdentifier;
#XmlAttribute(name = "return-object")
private boolean returnObject;
#XmlAttribute(name = "entry-point")
private String entryPoint;
private Object fact;
.
.
setters and gettes
com.practise.Employee.java
#XmlRootElement(name="kewill.com.kewill.practoise.Employee")
#XmlAccessorType(XmlAccessType.FIELD)
public class Employee implements java.io.Serializable
{
static final long serialVersionUID = 1L;
#org.kie.api.definition.type.Label("Name")
private java.lang.String name;
#org.kie.api.definition.type.Label("Id")
private java.lang.Integer id;
#org.kie.api.definition.type.Label("Age")
private int age;
#org.kie.api.definition.type.Label(value = "valid")
private java.lang.Boolean valid;
.
. setters and getters
I think it is possible through xtream api but I want to use JAXB please provide me the solution in jaxb.
In Insert.java
added Annotation for
private Object fact;
as
#XmlAnyElement(lax = true)
private Object fact;
Now it is giving expected output.

Categories

Resources