Accessing a specific section of an XML document using Unmarshal - java

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

Related

jaxb nested list elements returns null

I am trying to convert xml to java object using following jaxb code.
When i unmarshall the xml file i get value only for the version attribute in Settings element. Connections value is coming as null.
Please help me find out my mistake(s).WHat more details can i add?
PS:Kindly excuse my beginner level knowledge in java.
XML File:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xml>
<Settings version="3" xmlns="urn:Adapter-v3">
<Connections>
<Connection name ="Dev" description="DEV">
<Share version="CS" siteURL="https://example.com" />
</Connection>
<Connection name ="Dev1" description="DEV1">
<Share version="OM" siteURL="https://example.com" />
</Connection>
</Connections>
</Settings>
POJO classes:
#XmlRootElement(name="Settings", namespace="urn:Adapter-v3")
public class Settings {
Connections connections;
private String version;
#XmlElement(name="Connections")
public Connections getConnections() {
return connections;
}
public void setConnections(Connections connections) {
this.connections = connections;
}
#XmlAttribute(name="version")
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}
#XmlRootElement(name="Connections ")
public class Connections {
List<Connection> connection;
#XmlElement(name="Connection")
public List<Connection> getConnection() {
return connection;
}
public void setConnection(List<Connection> connection) {
this.connection = connection;
}
}
#XmlRootElement(name="Connection")
public class Connection {
private String name;
private String description;
Share share;
#XmlAttribute(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlAttribute(name="description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#XmlElement(name="Share")
public Share getShare() {
return share;
}
public void setShare(Share share) {
this.share = share;
}
}
#XmlRootElement(name="Share")
public class Share {
private String version;
private String siteUrl;
#XmlAttribute(name="version")
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
#XmlAttribute(name="siteURL")
public String getSiteUrl() {
return siteUrl;
}
public void setSiteUrl(String siteUrl) {
this.siteUrl = siteUrl;
}
}
MAIN FILE
public class JAXB {
public static void main(String[] args) {
JAXBContext jaxbContext;
Settings ha = null;
File fileName = new File("Config.xml");
try {
jaxbContext = JAXBContext.newInstance(Settings.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ha = (Settings)jaxbUnmarshaller.unmarshal(fileName);
}
catch(JAXBException e) {
e.printStackTrace();
}}
You have specified the namespace for the #XmlRootElement, but not for other elements. #XmlElement(name="Connections") maps the property as Connections element, without namespace.
Either add namespace="urn:Adapter-v3" to all other elements, or, better add a package-info.java to the package:
#javax.xml.bind.annotation.XmlSchema(
namespace = "urn:Adapter-v3",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.acme.foo;

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

How to Convert Java Object to XML object with java keyword

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.

Jaxb unmarshall returning null values

Hi I am new to Jaxb and trying to unmarshall a xml file through jaxb. I have added the xmpproporder and name fields correctly.
However two of my XML fields are populating as null while the others are populating perfectly.
My xml file is :-
<tables>
<table id="1">
<name>test1</name>
<schema>validator_test</schema>
<rowCountToValidate>7</rowCountToValidate>
<columnTypeCheckRequired>FALSE</columnTypeCheckRequired>
<additionalColumns>column1,column2</additionalColumns>
<targetName>target1</targetName>>
</table>
<table id="2">
<schema>validator_test</schema>
<name>validate_external1</name>
<rowCountToValidate>1</rowCountToValidate>
<columnTypeCheckRequired>FALSE</columnTypeCheckRequired>
<additionalColumns>column1,column2</additionalColumns>
</table>
</tables>
My code to unmarshall the elements is :
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
#XmlRootElement(name = "table")
#XmlType(propOrder = { "name", "schema","rowCountToValidate","columnTypeCheckRequired","additionalColumns","targetName"})
#Service
public class TableInfo {
private static final boolean TRUE = true;
#Value("${default.row.count.to.validate}")
private Integer defaultRowCountToValidate;
/**
*
*/
public TableInfo() {
}
private String name;
private String schema;
private Integer rowCountToValidate;
private String targetName;
private String columnTypeCheckRequired;
private String additionalColumns;
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElement(name = "schema")
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
#XmlElement(name = "rowCountToValidate")
public Integer getRowCountToValidate() {
return rowCountToValidate;
}
#XmlElement(name = "columnTypeCheckRequired")
public String getcolumnTypeCheckRequired(){
return columnTypeCheckRequired;
}
#XmlElement(name = "additionalColumns")
public String getadditionalColumns(){
return additionalColumns;
}
public void setRowCountToValidate(Integer rowCountToValidate) {
// If user configured value is not null and greater than zero then set
// the value otherwise use default value
if ((null != rowCountToValidate) && (rowCountToValidate.intValue() > 0)) {
this.rowCountToValidate = rowCountToValidate;
}else {
this.rowCountToValidate = defaultRowCountToValidate;
}
}
#XmlElement(name = "targetName")
public String getTargetName() {
return targetName;
}
public void setTargetName(String targetName) {
this.targetName = targetName;
}
public void setColumnTypeCheckRequired(String columnTypeCheckRequired) {
this.columnTypeCheckRequired = columnTypeCheckRequired;
}
public void setAdditionalColumns(String additionalColumns) {
this.additionalColumns = additionalColumns;
}
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}}
I am getting null values in columnTypeCheckRequired and additionalColumns. However other fields are populating correctly. Is there some other field or setting that I need to set?
I am completely new to Jaxb! Can someone please help me understand the error ?
You must change following getter, using camel case style. C and A capital case.
#XmlElement(name = "columnTypeCheckRequired")
public String getColumnTypeCheckRequired() {
return columnTypeCheckRequired;
}
#XmlElement(name = "additionalColumns")
public String getAdditionalColumns() {
return additionalColumns;
}

convert xml to java object using jaxb (unmarshal)

I have the following XML and I need to convert it into a java object.
<tests>
<test-data>
<title>BookTitle</title>
<book>BookName</book>
<count>64018</count>
<test-data>
<title>Book title1</title>
<book>Book Name1</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title2</title>
<book>Book Name3</book>
<count>5</count>
</test-data>
<test-data>
<title>Book title3</title>
<book>Book Name3</book>
<count>4</count>
</test-data>
</test-data>
</tests>
I am not sure what will be my pojo when I use JAXB to convert it.
I created the following POJOs as per my understanding:
public class Tests {
TestData testData;
public TestData getTestData() {
return testData;
}
public void setTestData(TestData testData) {
this.testData = testData;
}
}
public class TestData {
String title;
String book;
String count;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBook() {
return book;
}
public void setBook(String book) {
this.book = book;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
}
Tests
On the Tests class we will add an #XmlRootElement annotation. Doing this will let your JAXB implementation know that when a document starts with this element that it should instantiate this class. JAXB is configuration by exception, this means you only need to add annotations where your mapping differs from the default. Since the testData property differs from the default mapping we will use the #XmlElement annotation. You may find the following tutorial helpful: http://wiki.eclipse.org/EclipseLink/Examples/MOXy/GettingStarted
package forum11221136;
import javax.xml.bind.annotation.*;
#XmlRootElement
public class Tests {
TestData testData;
#XmlElement(name="test-data")
public TestData getTestData() {
return testData;
}
public void setTestData(TestData testData) {
this.testData = testData;
}
}
TestData
On this class I used the #XmlType annotation to specify the order in which the elements should be ordered in. I added a testData property that appeared to be missing. I also used an #XmlElement annotation for the same reason as in the Tests class.
package forum11221136;
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlType(propOrder={"title", "book", "count", "testData"})
public class TestData {
String title;
String book;
String count;
List<TestData> testData;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBook() {
return book;
}
public void setBook(String book) {
this.book = book;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
#XmlElement(name="test-data")
public List<TestData> getTestData() {
return testData;
}
public void setTestData(List<TestData> testData) {
this.testData = testData;
}
}
Demo
Below is an example of how to use the JAXB APIs to read (unmarshal) the XML and populate your domain model and then write (marshal) the result back to XML.
package forum11221136;
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Tests.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum11221136/input.xml");
Tests tests = (Tests) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(tests, System.out);
}
}

Categories