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.
Related
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;
}
}
I'm trying to create mobile sitemap using JAXB. According to google documentation, it should have following format:
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0">
<url>
<loc>http://mobile.example.com/article100.html</loc>
<mobile:mobile/>
</url>
</urlset>
To solve this problem I created following beans:
URL.java :
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
#XmlType(propOrder = {"loc"})
public class URL {
private String loc;
#XmlElement
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
URLSet.java
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="urlset")
public class URLSet{
private List<URL> urlset;
#XmlAttribute(name="xmlns")
private String xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9";
public URLSet() {
urlset = new ArrayList<URL>();
}
#XmlElement(name="url")
public List<URL> getUrlset() {
return urlset;
}
public void setUrlset(List<URL> urlset) {
this.urlset = urlset;
}
}
marshalling:
List<URL> list = new ArrayList<URL>();
URLSet urlSet = new URLSet();
for(int i = 0 ; i < 5 ; i++) {
URL url = new URL();
url.setLoc("www.test" + i + ".com");
list.add(url);
}
urlSet.setUrlset(list);
JAXBContext jaxbContext = JAXBContext.newInstance(URLSet.class);
Marshaller m = jaxbContext.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
//m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
//m.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
//m.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
StringWriter sw = new StringWriter();
m.marshal(urlSet,sw);
log.info("\n" + sw.toString() + "\n");
The questions are: how can I add static <mobile:mobile/> child to every node? how should I name mobile sitemap file in case I store this together with desktop "sitemap.xml" ? Thanks in advance.
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 am trying to read in some data from an XML file and having some trouble, the XML I have is as follows:
<xml version="1.0" encoding="UTF-8"?>
<EmailSettings>
<recipient>test#test.com</recipient>
<sender>test2#test.com</sender>
<subject>Sales Query</subject>
<description>email body message</description>
</EmailSettings>
I am trying to read these values as strings into my Java program, I have written this code so far:
private static Document getDocument (String filename){
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setValidating(false);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(filename));
}
catch (Exception e){
System.out.println("Error reading configuration file:");
System.out.println(e.getMessage());
}
return null;
}
Document doc = getDocument(configFileName);
Element config = doc.getDocumentElement();
I am struggling with reading in the actual string values though.
One of the possible implementations:
File file = new File("userdata.xml");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
String usr = document.getElementsByTagName("user").item(0).getTextContent();
String pwd = document.getElementsByTagName("password").item(0).getTextContent();
when used with the XML content:
<credentials>
<user>testusr</user>
<password>testpwd</password>
</credentials>
results in "testusr" and "testpwd" getting assigned to the usr and pwd references above.
Reading xml the easy way:
http://www.mkyong.com/java/jaxb-hello-world-example/
package com.mkyong.core;
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;
}
}
.
package com.mkyong.core;
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("mkyong");
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_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(customer, file);
jaxbMarshaller.marshal(customer, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
If using another library is an option, the following may be easier:
package for_so;
import java.io.File;
import rasmus_torkel.xml_basic.read.TagNode;
import rasmus_torkel.xml_basic.read.XmlReadOptions;
import rasmus_torkel.xml_basic.read.impl.XmlReader;
public class Q7704827_SimpleRead
{
public static void
main(String[] args)
{
String fileName = args[0];
TagNode emailNode = XmlReader.xmlFileToRoot(new File(fileName), "EmailSettings", XmlReadOptions.DEFAULT);
String recipient = emailNode.nextTextFieldE("recipient");
String sender = emailNode.nextTextFieldE("sender");
String subject = emailNode.nextTextFieldE("subject");
String description = emailNode.nextTextFieldE("description");
emailNode.verifyNoMoreChildren();
System.out.println("recipient = " + recipient);
System.out.println("sender = " + sender);
System.out.println("subject = " + subject);
System.out.println("desciption = " + description);
}
}
The library and its documentation are at rasmustorkel.com
Avoid hardcoding try making the code that is dynamic below is the code it will work for any xml I have used SAX Parser you can use dom,xpath it's upto you
I am storing all the tags name and values in the map after that it becomes easy to retrieve any values you want I hope this helps
SAMPLE XML:
<parent>
<child >
<child1> value 1 </child1>
<child2> value 2 </child2>
<child3> value 3 </child3>
</child>
<child >
<child4> value 4 </child4>
<child5> value 5</child5>
<child6> value 6 </child6>
</child>
</parent>
JAVA CODE:
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class saxParser {
static Map<String,String> tmpAtrb=null;
static Map<String,String> xmlVal= new LinkedHashMap<String, String>();
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, VerifyError {
/**
* We can pass the class name of the XML parser
* to the SAXParserFactory.newInstance().
*/
//SAXParserFactory saxDoc = SAXParserFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", null);
SAXParserFactory saxDoc = SAXParserFactory.newInstance();
SAXParser saxParser = saxDoc.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
String tmpElementName = null;
String tmpElementValue = null;
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
tmpElementValue = "";
tmpElementName = qName;
tmpAtrb=new HashMap();
//System.out.println("Start Element :" + qName);
/**
* Store attributes in HashMap
*/
for (int i=0; i<attributes.getLength(); i++) {
String aname = attributes.getLocalName(i);
String value = attributes.getValue(i);
tmpAtrb.put(aname, value);
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(tmpElementName.equals(qName)){
System.out.println("Element Name :"+tmpElementName);
/**
* Retrive attributes from HashMap
*/ for (Map.Entry<String, String> entrySet : tmpAtrb.entrySet()) {
System.out.println("Attribute Name :"+ entrySet.getKey() + "Attribute Value :"+ entrySet.getValue());
}
System.out.println("Element Value :"+tmpElementValue);
xmlVal.put(tmpElementName, tmpElementValue);
System.out.println(xmlVal);
//Fetching The Values From The Map
String getKeyValues=xmlVal.get(tmpElementName);
System.out.println("XmlTag:"+tmpElementName+":::::"+"ValueFetchedFromTheMap:"+getKeyValues);
}
}
#Override
public void characters(char ch[], int start, int length) throws SAXException {
tmpElementValue = new String(ch, start, length) ;
}
};
/**
* Below two line used if we use SAX 2.0
* Then last line not needed.
*/
//saxParser.setContentHandler(handler);
//saxParser.parse(new InputSource("c:/file.xml"));
saxParser.parse(new File("D:/Test _ XML/file.xml"), handler);
}
}
OUTPUT:
Element Name :child1
Element Value : value 1
XmlTag:<child1>:::::ValueFetchedFromTheMap: value 1
Element Name :child2
Element Value : value 2
XmlTag:<child2>:::::ValueFetchedFromTheMap: value 2
Element Name :child3
Element Value : value 3
XmlTag:<child3>:::::ValueFetchedFromTheMap: value 3
Element Name :child4
Element Value : value 4
XmlTag:<child4>:::::ValueFetchedFromTheMap: value 4
Element Name :child5
Element Value : value 5
XmlTag:<child5>:::::ValueFetchedFromTheMap: value 5
Element Name :child6
Element Value : value 6
XmlTag:<child6>:::::ValueFetchedFromTheMap: value 6
Values Inside The Map:{child1= value 1 , child2= value 2 , child3= value 3 , child4= value 4 , child5= value 5, child6= value 6 }
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)