Get particular object in xml based on supplied criteria - java

I am new born for Jaxb and trying to do read/write operation in xml.
I am done with the write operation but having trouble with the read one.
I have the following xml-
<docOperations>
<SkuSlabs id="1">
<docId>677-WORK</docId>
<itemIds>11</itemIds>
<itemName>new item addedaaaaaa</itemName>
</SkuSlabs>
<SkuSlabs id="2">
<docId>699-WORK</docId>
<itemIds>21</itemIds>
<itemName>extra</itemName>
</SkuSlabs>
</docOperations>
Now i want to unmarshal the SkuSlabs object based on the condition supplied 'where id = 1', but don't know how to achieve that.
Please help.

Here you are (as you want add same access modifiers to attributes):
package pl.skuslab;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "SkuSlabs")
#XmlAccessorType(XmlAccessType.FIELD)
public class SkusLab {
#XmlAttribute
int id;
String docId;
int itemIds;
String itemName;
public SkusLab(int id, String docId, int itemIds, String itemName) {
super();
this.id = id;
this.docId = docId;
this.itemIds = itemIds;
this.itemName = itemName;
}
public SkusLab() {
super();
}
#Override
public String toString() {
return "SkusLab [id=" + id + ", docId=" + docId + ", itemIds=" + itemIds + ", itemName=" + itemName + "]";
}
}
Class DocOperation:
package pl.skuslab;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class DocOperation {
#XmlElement(name = "SkuSlabs")
List<SkusLab> docOperations = new ArrayList<SkusLab>();
}
Class with the main function. Firstly I generate XML like you wrote in question, then I unmarshall xml to obejcts. First obejct is printed.
package pl.skuslab;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class SkusLabJaxb {
private static JAXBContext jc;
static {
try {
jc = JAXBContext.newInstance(DocOperation.class);
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
private static Marshaller getMarshaller() {
try {
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
return marshaller;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
private static Unmarshaller getUnmarshaller() {
try {
Unmarshaller unmarshaller = jc.createUnmarshaller();
return unmarshaller;
} catch (JAXBException e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
String xml = "";
try {
DocOperation doper = new DocOperation();
doper.docOperations.add(new SkusLab(1, "677-WORK", 11, "new item addedaaaaaa"));
doper.docOperations.add(new SkusLab(2, "699-WORK", 21, "extra"));
StringWriter sw = new StringWriter();
getMarshaller().marshal(doper, sw);
xml = sw.toString();
System.out.println(xml);
} catch (JAXBException e) {
e.printStackTrace();
}
try {
DocOperation docOperation = (DocOperation) getUnmarshaller().unmarshal(
new StringReader(xml));
System.out.println(docOperation.docOperations.get(0).toString());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

Related

Parser to read multiple xml file with same XSD and XSLT

I want to read the data from multiple XML files based on the XSD document and the structure of one XML file will not be the same as to another but will follow the xsd schema. Also, the xmls are nested xmls.Can someone help me with it so that I can use the already created utility and add the attributes to it? I need a XML parser which parses each xml file(They are different) based on the xsd schema and returns me a list of the map so that the data can be matched with the DB data.
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Test {
public static void main(String[] args) {
Customer customer = new Customer();
try {
File file = new File("SalesPoslog20200225104558676.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Customer {
int organizationID;
int retailStoreID;
int workstationID;
int tillID;
int sequenceNumber;
public int organizationID() {
return organizationID;
}
#XmlElement
public void RetailStoreID(int retailStoreID) {
this.retailStoreID = retailStoreID;
}
public int workstationID() {
return workstationID;
}
#XmlAttribute
public void RetailStoreId(int RetailStoreId) {
this.retailStoreID = retailStoreID;
}
}

jaxbUnmarshaller is not able to unmarchal a japanese characters

I have a xml which is having japanese characters. The Xml is getting marshalled correctly but which jaxbUnmarshalling all the characters are getting converted into '?'
Please find the Code Below :-
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class Customer {
String name;
int age;
int id;
public String getName() {
return name;
}
#XmlElement
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
#XmlElement
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
#XmlAttribute
public void setId(int id) {
this.id = id;
}
}
JAXBExample
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class JAXBExample {
public static void main(String[] args) {
Customer customer = new Customer();
customer.setId(100);
customer.setName("株式会社三菱東京UFJ銀行");
customer.setAge(29);
try {
File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Conversion.java
public class Conversion {
public static void main(String[] args) {
try {
File file = new File("C:\\file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Customer customer = (Customer) jaxbUnmarshaller.unmarshal(file);
System.out.println(customer.getName());
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
OutPUT :-
XML :-
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<customer id="100">
<age>29</age>
<name>株式会社三菱東京UFJ銀行</name>
</customer>
After running the Conversion.java class i am getting the below output:-
Customer Name ????????UFJ??
Please help i have searched the net but could not find any solution.
Try constructing a Reader yourself with the correct encoding and feed that Reader to Unmarshaller#unmarshal() instead of your File:
File file = new File("C:\\file.xml");
try (Reader reader = new InputStreamReader(new FileInputStream(file), "utf-8")) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(Customer.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Customer customer = (Customer) jaxbUnmarshaller.unmarshal(reader);
System.out.println(customer.getName());
} catch (JAXBException e) {
e.printStackTrace();
}
}
Also, if your platform encoding is something like latin1, then System.out uses it and corrupts the data being output (replacing it with question marks). Please run your program like this:
java -Dfile.encoding=utf-8 JAXBExample
By the way, this may be sufficient by itself, without the Reader-related twist, to solve the problem, as unmarshal() method should respect encoding specified in the XML file.

xstream to parse xml to java object with xml namespace

Hi I need to parse xml to object. I am trying to xstream with stax as my xml has namespace. I am getting error because of xsi:schemalocation.
Can anyone help how to configure schemalocation xsi?
I am getting below error:
Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributePrefixUnbound?n:contactDelData&xsi:schemaLocation&xsi
ContactDelData.java
public class ContactDelData {
private String contactId;
private String roid;
private String schemaLocation;
}
ContactDelParser.java
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.QNameMap;
import com.thoughtworks.xstream.io.xml.StaxDriver;
public class ContactDelParser {
public static void main(String[] args){
String xmlString = "<n:contactDelData
xmlns:n=\"http://www.nominet.org.uk/epp/xml/std-notifications-1.2\"
xsi:schemaLocation=\"http://www.nominet.org.uk/epp/xml/std-notifications-1.2 std-notifications-1.2.xsd\"><n:contactId> EPP-AB2345</n:contactId>
<n:roid>1002703-UK </n:roid></n:contactDelData>";
String namespaceURI="http://www.nominet.org.uk/epp/xml/std-notifications-1.2 std-notifications-1.2.xsd";
String alias="n";
String mappingObjName="contactDelData";
Class response=ContactDelData.class;
QNameMap qmap = new QNameMap();
QName qname = new QName(namespaceURI, "alias", alias);
qmap.registerMapping(qname, AbuseFeedInfoData.class);
StaxDriver staxDriver = new StaxDriver(qmap);
XStream xstream2 = new XStream(staxDriver);
xstream2.alias(mappingObjName, response);
//xstream2.useAttributeFor(response, "xmlns");
//xstream2.aliasAttribute("xsi:schemaLocation", "schemaLocation");
staxDriver.getInputFactory().setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
try {
Object poll = xstream2.fromXML(xmlString);
System.out.println(poll.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}

Unable to retrieve complete text from an element using JAXB

I am trying to retrieve text in using unmarshalling example of JAXB but unable to retrieve the within ... tag. This is my first question and hence quite unsure on indenting my code, but here it goes :
LangFlag.java
package IDJAXBParser;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlType( propOrder = { "name", "description", "match", "context" } )
#XmlRootElement( name = "langFlag" )
public class LangFlag
{
String name;
public String getName()
{
return name;
}
#XmlAttribute( name = "name" )
public void setName( String name )
{
this.name = name;
}
String description;
public String getDescription()
{
return description;
}
#XmlElement( name = "description" )
public void setDescription( String description )
{
this.description = description;
}
String context;
#XmlAnyElement(BioHandler.class)
public String getContext()
{
return context;
}
public void setContext( String context )
{
this.context = context;
}
List<String> match;
public List<String> getMatch()
{
return match;
}
#XmlElement( name = "match" )
public void setMatch( List<String> match )
{
this.match = match;
}
#Override
public String toString()
{
StringBuffer str = new StringBuffer( "Name: " + getName() + "\n" );
str.append("Description:" + getDescription() + "\n");
str.append("Context:" + getContext() + "\n");
str.append("Match:" + getMatch() + "\n");
str.append("\n");
return str.toString();
}
}
ListOfLangFlags.java
package IDJAXBParser;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement( name = "listOfLangFlags" )
public class ListOfLangFlags
{
List<LangFlag> listOfLangFlags;
public List<LangFlag> getLangFlags()
{
return listOfLangFlags;
}
/**
* element that is going to be marshaled in the xml
*/
#XmlElement( name = "langFlag" )
public void setLangFlags( List<LangFlag> listOfLangFlags )
{
this.listOfLangFlags = listOfLangFlags;
}
public void add( LangFlag langFlag )
{
if( this.listOfLangFlags == null )
{
this.listOfLangFlags = new ArrayList<LangFlag>();
}
this.listOfLangFlags.add( langFlag );
}
#Override
public String toString()
{
StringBuffer str = new StringBuffer();
for( LangFlag langFlag : this.listOfLangFlags )
{
str.append( langFlag.toString() );
}
return str.toString();
}
}
UnMarshalJAXVBComplete.java
package IDJAXBParser;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import IDJAXBParser.ListOfLangFlags;
public class UnMarshalJAXVBComplete
{
public static void main( String[] args )
{
try
{
File file = new File( "testv1.xml" );
JAXBContext jaxbContext = JAXBContext.newInstance( ListOfLangFlags.class );
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ListOfLangFlags langFlags = (ListOfLangFlags)jaxbUnmarshaller.unmarshal( file );
System.out.println( langFlags );
}
catch( JAXBException e )
{
e.printStackTrace();
}
}
}
This is my XML document :
<listOfLangFlags>
<langFlag name="Lang Flag Name">
<description>Lang Flag Description</description>
<context begin="0" end="100">I am so <span class="locality">blue </span>
I'm greener than purple. </context>
<suggestions/>
<match>I am so</match>
<match>blue</match>
</langFlag>
</listOfLangFlags>
BioHandler.java
package IDJAXBParser;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.DomHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class BioHandler implements DomHandler<String, StreamResult> {
private static final String BIO_START_TAG = "<context>";
private static final String BIO_END_TAG = "</context>";
private StringWriter xmlWriter = new StringWriter();
public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
xmlWriter.getBuffer().setLength(0);
return new StreamResult(xmlWriter);
}
public String getElement(StreamResult rt) {
String xml = rt.getWriter().toString();
int beginIndex = xml.indexOf(BIO_START_TAG) + BIO_START_TAG.length();
int endIndex = xml.indexOf(BIO_END_TAG);
return xml.substring(beginIndex, endIndex);
}
public Source marshal(String n, ValidationEventHandler errorHandler) {
try {
String xml = BIO_START_TAG + n.trim() + BIO_END_TAG;
StringReader xmlReader = new StringReader(xml);
return new StreamSource(xmlReader);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
Any help would be appreciated! Thanks in advance
Here is a DomHandler implementation which convert between DOM object and String.
import java.io.StringReader;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.DomHandler;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class BioHandler implements DomHandler<String, DOMResult> {
private StringBuilder buffer = new StringBuilder();
public DOMResult createUnmarshaller(ValidationEventHandler errorHandler) {
return new DOMResult();
}
public String getElement(DOMResult rt) {
Node n = rt.getNode();
Element ele = null;
if (n instanceof Document) {
ele = ((Document)n).getDocumentElement();
} else if (n instanceof DocumentFragment) {
ele = (Element)n.getChildNodes().item(0);
}
//StringBuilder sb = new StringBuilder(); //only capture the text under current node.
if (ele != null && "context".equals(ele.getLocalName())) {
try {
NodeList nl = (NodeList)XPathFactory.newInstance().newXPath()
.compile("descendant::text()").evaluate(ele, XPathConstants.NODESET);
int length = nl.getLength();
for (int i = 0; i < length; i++) {
buffer.append(nl.item(i).getTextContent());
}
} catch (XPathExpressionException e) {
throw new RuntimeException(e);
}
}
//for problem tracing
//System.err.println("BioHandler.getElement(), ele="+ele.getLocalName() +", result=["+result+"]");
return buffer.toString();
}
public Source marshal(String n, ValidationEventHandler errorHandler) {
try {
String xml = "<context>" + n.trim() + "</context>";
StringReader xmlReader = new StringReader(xml);
return new StreamSource(xmlReader);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
During my testing, the unknown <suggestions/> element is handled by the same object. So I declare buffer as class variable and output captured content every time.

Java: jaxb Generircs

How can I get jaxb to bind to my Vector? I cannot seem to get it to bind a Vector that contains generics as it complains that it cannot recognize my class "shape" or any of its subtypes.. "[javax.xml.bind.JAXBException: class shape.shape nor any of its super class is known to this context.]"?
import java.util.Vector;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "XVector")
public class XVector<shape> {
private Vector<shape> q;
public XVector() {}
#XmlElement(name = "q")
public Vector<shape> getVector() {
return q;
}
public void setVector(Vector<shape> q) {
this.q = q;
}
}
I get the following errors:
javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class shape.Rectangle nor any of its super class is known to this context.]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:317)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:243)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:75)
public void saveFile(File filename) {
try {
FileOutputStream fout = new FileOutputStream(filename);
objs.setVector(objVec);
JAXBContext context = JAXBContext.newInstance(XVector.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(objs, fout);
fout.close();
} catch (JAXBException e) {
e.printStackTrace ();
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, ex.toString(), "Error", JOptionPane.ERROR_MESSAGE);
}
}
You should include all required classes in the JAXBContext
JAXBContext context = JAXBContext.newInstance(XVector.class, shape.class);
(note: the convention dictates that Shape should be capitalized)

Categories

Resources