Java - Getting a ElementList attribute with SimpleXML (Android/Retrofit) - java

I'm trying to parse an XML response that looks like this with SimpleXML. It's very similar to the example shown at the simple xml tutorial page
http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#javabean
<response>
<version>1.0</version>
<code>1</code>
<message>Report generated</message>
<records total="365">
<record rowId="1" data1="1234" data2="abc" />
<record rowId="2" data1="5678" data2="def" />
<record rowId="3" data1="9012" data2="ghi" />
</records>
</response>
The only difference I have, is my <records total="365"> tag has an attribute I need to collect so I can determine if there's multiple pages of results.
I've tried using their example, which resulted in this
public class Response {
private ArrayList<Record> records;
#Element
public String message;
#Element
public String code;
#Element
public String version;
#ElementList
public void setRecords(ArrayList<Record> records) {
if(records.isEmpty()) {
throw new IllegalArgumentException("Empty collection");
}
this.records = records;
}
#ElementList
public ArrayList<Record> getRecords() {
return records;
}
public class Record {
#Attribute public String data1;
#Attribute public String data2;
}
}
Aside from missing the Total attribute in the Records tag, this works correctly.
Whatever I try to do to get this Total tag out doesn't work though.
I've tried all sorts of combinations of making a Records class that holds the attribute and ArrayList instead, having it in the main object as a basic attribute, or trying to have a getter / setter in the main response object without any luck.
E.G.
public class Response {
#Element
public String message;
#Element
public String code;
#Element
public String version;
#Element
public Records records;
public class Records{
private ArrayList<Record> records;
#Attribute
public String total;
#ElementList
public void setRecords(ArrayList<Record> records) {
if(records.isEmpty()) {
throw new IllegalArgumentException("Empty collection");
}
this.records = records;
}
#ElementList
public ArrayList<Record> getRecords() {
return records;
}
}
public class Record {
#Attribute public String data1;
#Attribute public String data2;
}
}
I don't understand how to make the List object, and get an attribute from it.
Any help would be greatly appreciated, I'm not sure how to make it work, it seems like it should be so simple, but I'm obviously missing something.

Was able to get some help and this is what works
#Default(DefaultType.FIELD)
public class Response{
public String message;
public String code;
public String version;
public Records records;
public Records getRecords ()
{
return records;
}
public void setRecords (ArrayList<Record> records)
{
this.records.setRecord(records);
}
}
public class Records
{
#Attribute
public String total;
public ArrayList<Record> records;
public String getTotal ()
{
return total;
}
public void setTotal (String total)
{
this.total = total;
}
#ElementList(inline=true)
public ArrayList<Record> getRecord ()
{
return records;
}
#ElementList(inline=true)
public void setRecord (ArrayList<Record> record)
{
this.records = record;
}
}
public class Record {
#Attribute public String data1;
#Attribute public String data2;
}

Related

Jackson missing out values

I am trying to map a JSON to a simple Java DTO.
Here is my Java structure:
public class VirtualServerResponse {
private String kind;
private String selfLink;
private List<VirtualServer> items = new ArrayList<VirtualServer>();
//no arg constructor
//getters and setters
#JsonIgnoreProperties(ignoreUnknown = true)
public class VirtualServer {
public String kind;
public String name;
public String partition;
public String fullPath;
public String generation;
public String selfLink;
public String addressStatus;
public String autoLasthop;
public String cmpEnabled;
public String connectionLimit;
public String description;
public String destination;
public String enabled;
public String gtmScore;
public String ipProtocol;
public String mask;
public String mirror;
public String mobileAppTunnel;
public String nat64;
public String pool;
public String rateLimit;
public String rateLimitDstMask;
public String rateLimitMode;
public String rateLimitSrcMask;
public String serviceDownImmediateAction;
public String source;
public String sourcePort;
public String synCookieStatus;
public String translateAddress;
public String translatePort;
public String vlansEnabled;
public String vsIndex;
public PoolDTO assignedPool;
public VirtualServer() {
}
//getters and setters
Here is the JSON that should be mapped:
"kind":"tm:ltm:virtual:virtualcollectionstate",
"selfLink":"https://localhost/mgmt/tm/ltm/virtual?expandSubcollections=true&ver=13.1.1.2",
"items":[
{
"kind":"tm:ltm:virtual:virtualstate",
"name":"some_name_with:80",
"partition":"part",
"fullPath":"/part/name",
"generation":58670,
"selfLink":"https://localhost/mgmt/tm/ltm/virtual/~somelink",
"addressStatus":"yes",
"autoLasthop":"default",
"cmpEnabled":"yes",
"connectionLimit":0,
"description":"description",
"destination":"/part/1.1.1.1:80",
"enabled":true,
"gtmScore":0,
"ipProtocol":"tcp",
"mask":"255.255.255.255",
"mirror":"disabled",
"mobileAppTunnel":"disabled",
"nat64":"disabled",
"pool":"/pool",
"poolReference":{
"link":"https://localhost/mgmt/tm/ltm/pool/link"
},
"rateLimit":"disabled",
"rateLimitDstMask":0,
"rateLimitMode":"object",
"rateLimitSrcMask":0,
"serviceDownImmediateAction":"none",
"source":"0.0.0.0/0",
"sourceAddressTranslation":{
"type":"automap"
},
"sourcePort":"preserve",
"synCookieStatus":"not-activated",
"translateAddress":"enabled",
"translatePort":"enabled",
"vlansEnabled":true,
"vsIndex":137,
"vlans":[
"/LAN"
],
"vlansReference":[
{
"link":"https://localhost/mgmt/tm/net/vlan/~LAN?ver=13.1.1.2"
}
],
"policiesReference":{
"link":"https://localhost/mgmt/tm/ltm/virtual/policie",
"isSubcollection":true
},
"profilesReference":{
"link":"https://localhost/mgmt/tm/ltm/virtual/~name",
"isSubcollection":true,
"items":[
{
"kind":"tm:ltm:virtual:profiles:profilesstate",
"name":"stats",
"partition":"part",
"fullPath":"/part/stats",
"generation":3,
"selfLink":"https://localhost/mgmt/tm/ltm/virtual/~name",
"context":"all",
"nameReference":{
"link":"https://localhost/mgmt/tm/ltm/profile/statistics/~part~stats?ver=13.1.1.2"
}
},
{
"kind":"tm:ltm:virtual:profiles:profilesstate",
"name":"tcp",
"partition":"part",
"fullPath":"/part/tcp",
"generation":58670,
"selfLink":"https://localhost/mgmt/tm/ltm/virtual/~name",
"context":"all",
"nameReference":{
"link":"https://localhost/mgmt/tm/ltm/profile/tcp/~part~tcp?ver=13.1.1.2"
}
}
]
}
}, ... next item
The JSON is mapped by the whole JSON in one line:
while ((line = br.readLine()) != null) {
this.jsonResponse = m.readValue(line, VirtualServerResponse.class);
}
I do not need all the subitems in a item, so I used JsonIgnoreUnknown to let them off. However, there are only a few properties, that are mapped:
kind, name, partition, fullPath, generation, selfLink and description.
All others are null. Can someone help me?
It seems that there are properties at different levels.
You have mapped an object with all properties directly under the root, so all other nested properties are not visible.
If the json is something like:
{
"kind":"tm:ltm:virtual:virtualcollectionstate",
"selfLink":"https://localhost/mgmt/tm/ltm/virtual?expandSubcollections=true&ver=13.1.1.2",
"items":[
{
"kind":"tm:ltm:virtual:virtualstate",
"name":"some_name_with:80",
"partition":"part",
"fullPath":"/part/name",
...
}
]
}
You need to map it to an object similar to:
public class VirtualServer {
private String kind;
private String selfLink;
private List<VirtualServer.Item> items;
...
public static class Item {
private String kind;
private String name;
private String partition;
private String fullPath;
...
}
}

How to convert Java objects to XML element attributes using JAXB

How to convert java object to xml using JAXB to get the following xml:
<Case>
<Version>1.0</Version>
<Code>457123</Code>
<Meta uc=\"Sample\" pip=\"116.0.1.1\" lot=\"P\"/>
</Case>
There are many answers regarding how to get XML. I have gone through all those. But my question is how to get the XML as what I have shown. It contains a self-closing tag which even contains attributes.
I am using Eclipse IDE. Please suggest a method.
This is my case class:
import auth.Res.Meta;
#XmlRootElement (name="Case")
public class Test {
private Meta mt;
private String version;
private String code;
#XmlRootElement
public class Meta {
#XmlAttribute
private String uc;
#XmlAttribute
private String pip;
public String getUc() {
return uc;
}
public void setUc(String uc) {
this.uc = uc;
}
public String getPip() {
return pip;
}
public void setPip(String pip) {
this.pip = pip;
}
}
public Meta getMt() {
return mt;
}
public void setMt(Meta mt) {
this.mt = mt;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
Solution:
I solved it by creating seperate class for Meta as suggested by LazerBanana in the first answer.
This is how your Meta class should look like.
public class Meta {
private String uc;
private String pip;
private String lot;
public String getUc() {
return uc;
}
#XmlAttribute
public void setUc(String uc) {
this.uc = uc;
}
public String getPip() {
return pip;
}
#XmlAttribute
public void setPip(String pip) {
this.pip = pip;
}
public String getLot() {
return lot;
}
#XmlAttribute
public void setLot(String lot) {
this.lot = lot;
}
}
this is your Case class which is the root element
#XmlRootElement
public class Case {
private int version;
private String code;
private String id;
private Meta meta;
public int getVersion() {
return version;
}
#XmlElement
public void setVersion(int version) {
this.version = version;
}
public String getCode() {
return code;
}
#XmlElement
public void setCode(String code) {
this.code = code;
}
public String getId() {
return id;
}
#XmlElement
public void setId(String id) {
this.id = id;
}
public Meta getMeta() {
return meta;
}
#XmlElement
public void setMeta(Meta meta) {
this.meta = meta;
}
}
And this is the marshaling bit to the console and to the file it you want.
public class Main {
public static void main(String... args) {
Case fcase = new Case();
Meta meta = new Meta();
meta.setLot("asd");
meta.setPip("sdafa");
meta.setUc("asgd4");
fcase.setMeta(meta);
fcase.setVersion(1);
fcase.setId("sah34");
fcase.setCode("code34");
try {
// File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Case.class, Meta.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// jaxbMarshaller.marshal(fcase, file);
jaxbMarshaller.marshal(fcase, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Output:
<case>
<code>code34</code>
<id>sah34</id>
<meta lot="asd" pip="sdafa" uc="asgd4"/>
<version>1</version>
</case>
Next time please try to do more research i am not an expert and I just googled it.
https://www.mkyong.com/java/jaxb-hello-world-example/
i need to create a rest service which accepts xml of format i have gien. Thats y i need it in a single class.
#POST
#Path("/add")
#Consumes("application/xml")
#Produces("application/xml")
public Response getper(Test test)
{
String nam=test.getVersion();
int cd=test.getCode();
Res rs=new Res();
rs.setMessage(nam);
.
.
return Response.status(200).entity(rs).build();
}

Pulling XML child inner node from XML to Java Object using JAXB

I have been trying to pull a child node from an XML which I received from a SOAP as string. I can retrieve the parent node but couldn't retrieve the child node. I also surf the internet to see if I can get an answer but all to no avail. I saw some examples with direct child pulling, but that didn't solve my problem.
<response>
<code>1</code>
<list available="2">
<cart id="2" name="egg">
<stuff>
<id>001</id>
<name>Crew</name>
<shortname>C</shortname>
</stuff>
</cart>
<cart id="4" name="bread">
<stuff>
<id>004</id>
<name>Bread</name>
<shortname>B</shortname>
</stuff>
</cart>
</list>
</response>
Response Class
public class Response {
private String code;
private String list;
private String cart;
private Response.Stuff stuffs;
#XmlElement(name="code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
.
.
#XmlElement
public Response.Stuff getStuff() {
return this.stuffs;
}
public void setStuff(Response.Cart stuff) {
this.stuffs = stuff;
}
public static class Stuff {
private List<Stuff> stuff;
public List<Stuff> getStuff() {
if (stuff == null) {
stuff = new ArrayList<Stuff>();
}
return stuff;
}
}
}
Stuff Classs
public class Stuff {
private String id;
private String crew;
#XmlElement
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
.
.
}
Now my problem is how to pull child stuff content (i.e id,name and shortname) using JAXB.
I created class Response and Stuff and made stuff a list inside response but when ever I run the code it throws null exception.
PS: Please remember the XML is not a file its a string and am using StringReader class for the JAXB.unmarshal
JAXBContext jcontext= JAXBContext.newInstance();
unmarshaller um=jcontext.createUnmarshaller();
JAXBElement je=um.unmarshal(new File("pass xml file location"));
response r= getValue();
r.getlist().getcart().getstuff().getid().getValue();
try this one it may work
I finally solved my problem by restructuring the above class and creating a new one. See below the updated:
public class Response {
private String code;
private List list;
#XmlElement(name="code")
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
#XmlElement(name= "list")
public List getlist() {
return this.list;
}
public void setList(List list) {
this.list = list;
}
}
Class List
#XmlRootElement(name= "list")
public class List {
private List.Cart cart;
#XmlElement(name= "cart")
public List<Cart> getCart() {
return this.cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
#XmlRootElement(name= "cart")
public static class Cart {
private List<Stuff> stuff;
private List<Stuff> getStuff() {
if (stuff == null) {
stuff = new ArrayList();
}
return stuff;
}
}
}
With this, it was easy for me to marshal and unmarshal

How to set and get json from setter/getter class?

this is my pojo class and i want make method add diary in my diary services class then how to get and set json in this method and any other way to get and set json from setter/getter class.
public class Dairy extends BaseEntity {
public String dairyId;
public String dairyType;
public String productName;
private List<Dairy> dataList;
public List<Dairy> getDataList() {
return dataList;
}
public void setDataList(List<Dairy> dataList) {
this.dataList = dataList;
}
public String getDairyId() {
return dairyId;
}
public void setDairyId(String dairyId) {
this.dairyId = dairyId;
}
public String getDairyType() {
return dairyType;
}
public void setDairyType(String dairyType) {
this.dairyType = dairyType;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
If you hava json like this
product:{
dairyId:"1",
dairyType:"a",
productName:"New Year 2015"
}
You should get like
Dairy d=new Dairy();
You have to use jsonParser class.Then set value on object d.like
JSONObject jsonObject=getJSONObject("product");
d.setDairyId(jsonObject.getString("dairyId");
d.setDairyType(jsonObject.getString("dairyType");
d.setProductName(jsonObject.getString("productName");
To print this value you may use like:
System.out.println("Name is:"+d.getProductName());
I hope this will help to you :)

Accessing a specific section of an XML document using Unmarshal

i have an XML document that have some configuration information i have to access the information from a java class.I am able to access the information using java unmarshalling,but the problem is that i can not access a specific portion of the xml file.Every time i am accessing the information i have to take the root tag first i.e i only can access the root tag elements,but i need to access the tag that is in the another section.This is my XML file
<?xml version="1.0" encoding="UTF-8"?>
<adapter name="Hua_GPRS_CS5_4.7" type="ASN.1" version="1.0" description="Huawie GPRS Output CDR Version 4.7"
execclass="hua.gprs.HuaGPRSFileExecutor" parallel="1" mode="server" statusfile="HuaGPRSStatus.csv" merge_factor="1" active="true">
<dirconfig>
<Poll protocol="" host="" path="./data/huagprs/source" pwd="" user="" clogging="true" startdir="" enddir=""
pattern="(.*)\.(\d{6})(\d{6})(\d{4})_(.*)" metafields="fileName,exchange,fileDate,fileTime,fileSeq,junk"/>
<Source path="./data/huagprs/source" clogging="false"/>
<Backup path="./data/huagprs/backup" active="false"/>
<Staging path="./data/huagprs/staging" clogging="false"/>
<Output path="./data/huagprs/output" clogging="false" compress="gz"/>
<Error path="./data/huagprs/error" clogging="true"/>
<Target protocol="" host="" path="/" pwd="" user="" active="true"/>
</dirconfig>
<dbConf id="1" name ="jjj" drivername="oracle.jdbc.driver.OracleDriver" hostname="localhost" portname="1521" dbname="rrr" servicename="orcl" user="param" password="param" sid="orcl">
<TableConfig ID= "1" TableName="">
</TableConfig>
</dbConf>
</adapter>
i can access only the elements of the adapter tag.but what i need to use dbconf.. here i am posting the class es i am using to get the value of the adapter tag.The model class
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Adapter {
String name;
String type;
String version;
String description;
String execclass;
String parallel;
String mode;
String statusfile;
String merge_factor;
String active;
String drivername;
public String getDrivername() {
return drivername;
}
#XmlAttribute
public void setDrivername(String drivername) {
this.drivername = drivername;
}
public String getName() {
return name;
}
#XmlAttribute
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
#XmlAttribute
public void setType(String type) {
this.type = type;
}
public String getVersion() {
return version;
}
#XmlAttribute
public void setVersion(String version) {
this.version = version;
}
public String getDescription() {
return description;
}
#XmlAttribute
public void setDescription(String description) {
this.description = description;
}
public String getExecclass() {
return execclass;
}
#XmlAttribute
public void setExecclass(String execclass) {
this.execclass = execclass;
}
public String getParallel() {
return parallel;
}
#XmlAttribute
public void setParallel(String parallel) {
this.parallel = parallel;
}
public String getMode() {
return mode;
}
#XmlAttribute
public void setMode(String mode) {
this.mode = mode;
}
public String getStatusfile() {
return statusfile;
}
#XmlAttribute
public void setStatusfile(String statusfile) {
this.statusfile = statusfile;
}
public String getMerge_factor() {
return merge_factor;
}
#XmlAttribute
public void setMerge_factor(String merge_factor) {
this.merge_factor = merge_factor;
}
public String getActive() {
return active;
}
#XmlAttribute
public void setActive(String active) {
this.active = active;
}
}
The main class to get the values
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class ReadXML {
/**
* #param args
*/
public static void main(String[] args) {
try {
File file = new File("./file/config.ds");
JAXBContext jaxbContext2 = JAXBContext.newInstance(Adapter.class);
Unmarshaller jaxbUnmarshaller2 = jaxbContext2.createUnmarshaller();
Adapter db2 = (Adapter) jaxbUnmarshaller2.unmarshal(file);
System.out.println(db2.active);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
You can use a StAX XMLStreamReader to advance parse the XML document. Then advance to the XML element you want to unmarshal. Then use the unmarshal method that takes XMLStreamReader as a parameter.
http://blog.bdoughan.com/2012/08/handle-middle-of-xml-document-with-jaxb.html

Categories