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;
}
}
Related
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.
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();
}
}
}
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);
}
}
}
I'm trying to marshall an object and replace some invarvalid char's after that. In this processes, the completed xml is not getting generated. I can only see 1024 chars in all the generated files.
package com.test;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Scanner;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.apache.log4j.Logger;
import org.xml.sax.SAXException;
import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
public class MessageParserComponent {
private static final Logger LOGGER = Logger.getLogger(MessageParserComponent.class);
public File marshalIXml(final Object obj, final String xsdSchema,
final String xmlFileName, final JAXBContext ctx) {
File xml = new File(xmlFileName);
try {
xml.createNewFile();
Marshaller marshaller = null;
marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
"http://www.db.com/tf " + xsdSchema);
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper",
new NamespacePrefixMapper() {
#Override
public String getPreferredPrefix(String arg0, String arg1,
boolean arg2) {
return "tf";
}
});
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
"http://www.db.com/tf " + xsdSchema);
marshaller.setSchema(getSchema(xsdSchema));
marshaller.marshal(obj, new StreamResult(xml));
xml = replaceInvalidChar('\u0007', '\n', xml);
xml = replaceInvalidString("ns2", "xsi", xml);
} catch (IOException e) {
LOGGER.error(e);
} catch (JAXBException e) {
LOGGER.error(e);
} catch (SAXException e) {
LOGGER.error(e);
}
return xml;
}
private Schema getSchema(String xsdSchema) throws SAXException {
SchemaFactory fact = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = fact.newSchema(this.getClass().getClassLoader()
.getResource(xsdSchema));
return schema;
}
private static File replaceInvalidString(String Target, String Dest,
File Source) throws IOException {
String xml_string;
xml_string = new Scanner(Source).useDelimiter("\\Z").next();
xml_string = xml_string.replace(Target, Dest);
FileOutputStream fi = new FileOutputStream(Source);
fi.write(xml_string.getBytes());
return Source;
}
public static File replaceInvalidChar(char Target, char Dest, File Source)
throws IOException {
String xml_string;
xml_string = new Scanner(Source).useDelimiter("\\Z").next();
xml_string = xml_string.replace(Target, Dest);
FileOutputStream fi = new FileOutputStream(Source);
fi.write(xml_string.getBytes());
return Source;
}
}
Is there a limit for string replacement?
Am I creating the file in a wrong way?
Note:
I'm storing file in UNIX log folder
I have java 6, JAXB 2.2
Any sort of help is highly appreciated.
Just check whether you annotated your object with jaxb annotations correctly.
And why are you setting Marshaller properties? do you want to use external schema to marshall your object? instead why don't you let jaxb to take care of all those things (if your objects are available in same workspace).
This sample program may be helpful to you.
http://www.mkyong.com/java/jaxb-hello-world-example/
and check this on too..
JAXB Marshaller : StringWriter output has a truncated tag value
truncated-tag-value
When you open a FileOutputStream you are responsible for closing. You should change your code to include the close() call.
FileOutputStream fi = new FileOutputStream(Source);
fi.write(xml_string.getBytes());
fi.close();
The issue was with the scanner, which is trying to find the EOF and not spooling the entire file. This is not happening in local development environment. Where as in the UNIX server, where my application is deployed the "end of input" is different, which caused this issue.
File f1 = new File(path);
StringBuilder f2 = new StringBuilder();
Scanner scanner = new Scanner(f1).useDelimiter("\\Z");
while (scanner.hasNext()) {
f2.append(scanner.next());
This completed the trick.
I do not know about the performance part of the scanner (taking only 1024 chars)when compared to other Buttered readers.
Any other solution which improves performance is highly appriciated.
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)