Something is wrong and application crashes. I am trying to parse xml text into java classes, I'm using XStream library. Code crashes after I use method fromXML. My code:
XML file looks like this:
<FilesManifest>
<Group>
<HeaderName>Pirmas hdr</HeaderName>
<Type>theory</Type>
<Piece>
<FileName>11.txt</FileName>
<HeadLine>hi1</HeadLine>
</Piece>
<Piece>
<FileName>22.txt</FileName>
<HeadLine>hi2</HeadLine>
</Piece>
</Group>
<Group>
<HeaderName>antras hdr</HeaderName>
<Type>theory</Type>
<Piece>
<FileName>33.txt</FileName>
<HeadLine>hi3</HeadLine>
</Piece>
<Piece>
<FileName>44.txt</FileName>
<HeadLine>hi4</HeadLine>
</Piece>
</Group>
<Group>
<HeaderName>tracias hdr</HeaderName>
<Type>test</Type>
<Piece>
<FileName>55.txt</FileName>
<HeadLine>hi5</HeadLine>
</Piece>
<Piece>
<FileName>66.txt</FileName>
<HeadLine>hi6</HeadLine>
</Piece>
</Group>
</FilesManifest>
My main function code:
String fileText = ReadFile();
XStream xstream = new XStream();
xstream.alias("FilesManifest", MyFileManager.class);
xstream.alias("Group", MyGroup.class);
xstream.alias("Piece", MyPiece.class);
MyFileManager data = (MyFileManager)xstream.fromXML(fileText);
And classes for xml parsing:
public class MyFileManager {
public List<MyGroup> getGroups() {
return groups;
}
public void setGroups(List<MyGroup> groups) {
this.groups = groups;
}
#XStreamImplicit(itemFieldName = "group")
private List<MyGroup> groups = new ArrayList<MyGroup>();
}
public class MyGroup {
private String headerName;
private String type;
#XStreamImplicit(itemFieldName = "piece")
private List<MyPiece> pieces = new ArrayList<MyPiece>();
public List<MyPiece> getPieces() {
return pieces;
}
public void setPieces(List<MyPiece> pieces) {
this.pieces = pieces;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getHeaderName() {
return headerName;
}
public void setHeaderName(String headerName) {
this.headerName = headerName;
}
}
public class MyPiece {
private String fileName;
private String headLine;
public String getHeadLine() {
return headLine;
}
public void setHeadLine(String headLine) {
this.headLine = headLine;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
}
So can you advice me that code would work correctly? Maybe there is other way to parse?
I could make your code work by fixing 2 main issues:
Your mapping is incomplete and not correct because you seem to forget that XML is case-sensitive which means that for example #XStreamImplicit(itemFieldName = "group") should be #XStreamImplicit(itemFieldName = "Group") and all the fields must be annotated with #XStreamAlias to provide an alias with the first character in capital.
You did not call processAnnotations(Class type) such that your annotations are not processed.
So at the end your code should be something like that:
Your POJOs:
public class MyFileManager {
...
#XStreamImplicit(itemFieldName = "Group")
private List<MyGroup> groups = new ArrayList<>();
}
public class MyGroup {
#XStreamAlias("HeaderName")
private String headerName;
#XStreamAlias("Type")
private String type;
#XStreamImplicit(itemFieldName = "Piece")
private List<MyPiece> pieces = new ArrayList<>();
...
}
public class MyPiece {
#XStreamAlias("FileName")
private String fileName;
#XStreamAlias("HeadLine")
private String headLine;
...
}
Your main function code:
...
// Process the provided annotations
xstream.processAnnotations(MyFileManager.class);
MyFileManager data = (MyFileManager)xstream.fromXML(fileText);
Related
I understand there may be cleaner ways to store these data, I'm skipping that part for the sake of my sanity in dealing with legacy code.
I want to store an object that looks like this in DynamoDB:
#DynamoDBTable(tableName="TableName")
public class MyItem {
// DynamoDB Attributes
private String hashKey;
private String someAttribute;
private Map<String, Config> configs;
#DynamoDBHashKey(attributeName = "hash_key")
public String getHashKey() {
return this.hashKey;
}
public void setHashKey(String hashKey) {
this.hashKey = hashKey;
}
#DynamoDBAttribute(attributeName = "some_attribute")
public String getSomeAttribute() {
return this.someAttribute;
}
public void setSomeAttribute(String someAttribute ) {
this.someAttribute = someAttribute;
}
#DynamoDBAttribute(attributeName = "configs")
public Map<String, Config> getConfigs() {
return this.configs;
}
public void setConfigs(Map<String, Config> configs)
{
this.configs = configs;
}
}
With a supplemental class
#DynamoDBDocument
public class Config {
private String field;
#DynamoDBAttribute(attributeName="field")
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
Will this work as written?
What would the resulting entry look like in DynamoDB for the following JSON:
{
"hash_key":"123",
"some_attribute":"attribute_value",
"a_config_key" : {
"field":"field_value"
}
}
I would recommend you to implement your own converter using #DynamoDbConvertedBy (the official dynamodb-enhanced client).
Hopefully, this sample is helpful: https://stackoverflow.com/a/70602166/12869305
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();
}
I am using JAXB to marshall a Bean object. I searched a lot, going through blogs but I couldn't find a viable solution. I am also new to JAXB, so any suggestion will be appreciated.
The required xml structure is :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<REPORT REPORT_YEAR="2016">
<STANDARD_FINANCIALS>
<BALANCE_SHEET>
<ASSET label = "ASSET">76</ASSET>
<LIABILITY label = "LIABILITY">90</LIABILITY>
</BALANCE_SHEET>
</STANDARD_FINANCIALS>
</REPORT>
And the POJO(bean) classes I am using are:
#XmlRootElement(name = "REPORT")
public class Report {
private String reportYear;
public String getReportYear() {
return reportYear;
}
#XmlAttribute(name = "REPORT_YEAR")
public void setReportYear(String reportYear) {
this.reportYear = reportYear;
}
private StandardFinancials financials;
public StandardFinancials getFinancials() {
return financials;
}
#XmlElement(name = "STANDARD_FINANCIALS")
public void setFinancials(StandardFinancials financials) {
this.financials = financials;
}
public Report(){
}
public Report(String reportYear, StandardFinancials financials) {
super();
this.reportYear = reportYear;
this.financials = financials;
}
}
And
public class StandardFinancials {
private BalanceSheet balanceSheet;
#XmlElement(name = "BALANCE_SHEET")
public void setBalanceSheet(BalanceSheet balanceSheet) {
this.balanceSheet = balanceSheet;
}
public StandardFinancials(BalanceSheet balanceSheet) {
super();
this.balanceSheet = balanceSheet;
}
}
And the other one is:
public class BalanceSheet {
private String liability;
private String asset;
public String getLiability() {
return liability;
}
#XmlElement(name = "LIABILITY")
public void setLiability(String liability) {
this.liability = liability;
}
public String getAsset() {
return asset;
}
#XmlElement(name = "ASSET")
public void setAsset(String asset) {
this.asset = asset;
}
public BalanceSheet(String liability, String asset) {
super();
this.liability = liability;
this.asset = asset;
}
}
And the main method is:
public class Jaxbmarshelling {
public static void main(String[] args) throws Exception {
JAXBContext context=JAXBContext.newInstance(Report.class);
Marshaller marshaller=context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
BalanceSheet balanceSheet = new BalanceSheet("90", "76");
StandardFinancials financials = new StandardFinancials(balanceSheet);
Report report = new Report("2016",financials);
StringWriter xml = new StringWriter();
marshaller.marshal(report, xml);
System.out.println(xml.toString());
}
}
but the output xml I get is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<REPORT REPORT_YEAR="2016">
<STANDARD_FINANCIALS>
<BALANCE_SHEET>
<ASSET>76</ASSET>
<LIABILITY>90</LIABILITY>
</BALANCE_SHEET>
</STANDARD_FINANCIALS>
</REPORT>
I am not able to get the label attribute of each element of balance sheet class.
Please guide me to get the required xml.
Make your asset and liability fields POJOs and you can use annotations to control their appearance:
public static class BalanceSheet {
private Entry liability;
private Entry asset;
public Entry getLiability() {
return liability;
}
#XmlElement(name = "LIABILITY")
public void setLiability(Entry liability) {
this.liability = liability;
}
public Entry getAsset() {
return asset;
}
#XmlElement(name = "ASSET")
public void setAsset(Entry asset) {
this.asset = asset;
}
public BalanceSheet(Entry asset, Entry liability) {
super();
this.liability = liability;
this.asset = asset;
}
}
public static class Entry {
private String label;
private int amount;
public int getAmount() {
return amount;
}
#XmlValue
public void setAmount(int amount) {
this.amount = amount;
}
public String getLabel() {
return label;
}
#XmlAttribute(name="label")
public void setLabel(String label) {
this.label = label;
}
public Entry() {
}
public Entry(String label, int amount) {
this.label = label;
this.amount = amount;
}
}
I create an java class:
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public String getReturncode() {
return returncode;
}
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
and other class:
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
}
And I Want to convert object ReturnObj to this XML
<return>
<returncode>1</returncode>
<returndesc>DANG_KY_THANH_CONG</returndesc>
<package>
<packagecode>BD30</packagecode>
<cycle>1</cycle>
<price>15000</price>
<desc> BD30</desc>
</package>
</return>
So how do I serialize an attribute pkg to package in XML? Because Java doesn't allow to name variable as an keyword anh package is an keyword in Java !
You can use JAXB marshling in your class it will convert the object to XML, here is link to help you JAXB Marshling
Try xstream
XStream xstream = new XStream();
xstream.alias("package", Pkg.class);
String xml = xstream.toXML(myReturnObj);
You can use JAXB API that comes with java for converting java object to XML.
Below is the code that will solve your requirement.
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "return")
public class ReturnObj {
private String returncode;
private String returndesc;
private Pkg pkg;
public Pkg getPkg() {
return pkg;
}
#XmlElement(name = "package")
public void setPkg(Pkg pkg) {
this.pkg = pkg;
}
public String getReturncode() {
return returncode;
}
#XmlElement(name = "returncode")
public void setReturncode(String returncode) {
this.returncode = returncode;
}
public String getReturndesc() {
return returndesc;
}
#XmlElement(name = "returndesc")
public void setReturndesc(String returndesc) {
this.returndesc = returndesc;
}
}
#XmlRootElement
public class Pkg {
private String packagecode;
private String cycle;
private String price;
private String desc;
public String getPackagecode() {
return packagecode;
}
#XmlElement(name="packagecode")
public void setPackagecode(String packagecode) {
this.packagecode = packagecode;
}
public String getCycle() {
return cycle;
}
#XmlElement(name="cycle")
public void setCycle(String cycle) {
this.cycle = cycle;
}
public String getPrice() {
return price;
}
#XmlElement(name="price")
public void setPrice(String price) {
this.price = price;
}
public String getDesc() {
return desc;
}
#XmlElement
public void setDesc(String desc) {
this.desc = desc;
}
}
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
private static final String FILE_NAME = "C:\\ru\\jaxb-returnObj.xml";
public static void main(String[] args) {
ReturnObj returnObj = new ReturnObj();
returnObj.setReturncode("1");
returnObj.setReturndesc("DANG_KY_THANH_CONG");
Pkg pkg = new Pkg();
pkg.setCycle("1");
pkg.setPrice("15000");
pkg.setDesc("BD30");
returnObj.setPkg(pkg);
jaxbObjectToXML(returnObj);
}
private static void jaxbObjectToXML(ReturnObj emp) {
try {
JAXBContext context = JAXBContext.newInstance(ReturnObj.class);
Marshaller m = context.createMarshaller();
// for pretty-print XML in JAXB
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
// Write to System.out, this will print the xml on console
m.marshal(emp, System.out);
// Write to File
m.marshal(emp, new File(FILE_NAME));
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Explanation:
#XmlRootElement: This is a must have annotation for the Object to be used in JAXB. It defines the root element for the XML content.
#XmlElement: This will create the element. If you want to give some other name to the xml element when converting java object to xml then you can pass name attribute to the #XmlElement Example:
#XmlElement(name = "package")
Execute above code to see the desired output.
Happy Coding.
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