I try to unmarshal a String using this code:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.namespace.QName;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.io.IOUtils;
import org.xml.sax.InputSource;
#XmlRootElement(name="Grid")
public class Marshal {
#XmlAttribute(name="Reload", required = false)
public int reload;
#XmlElementWrapper(name="Changes")
#XmlElement(name="I")
public List<XmlAttributeHolder> rowList = new ArrayList<XmlAttributeHolder>();
public static void main(String[] args) {
try {
JAXBContext jc = JAXBContext.newInstance(Marshal.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
// à€
String xmlString = "<Grid><IO/><Changes><I id=\"0\" Changed=\"1\" STT=\"à€\"/></Changes></Grid>";
InputStream inputStream = IOUtils.toInputStream(xmlString);
InputSource is = new InputSource(inputStream);
is.setEncoding("ISO-8859-1");
Marshal obj = (Marshal) unmarshaller.unmarshal(is);
System.out.println(xmlString);
for (int i=0;i<obj.rowList.size();i++) {
XmlAttributeHolder xah = obj.rowList.get(i);
System.out.println(xah.getAttrMap());
for (String formValue:xah.getAttrMap().values()) {
System.out.println(StringEscapeUtils.unescapeXml(formValue));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static class XmlAttributeHolder {
#XmlAnyAttribute
public Map<QName, String> attrMap = new HashMap<QName, String>();
public void addAttribute(String name, String value) {
attrMap.put(QName.valueOf(name), value);
}
public String getAttribute(String name) {
return attrMap.get(QName.valueOf(name));
}
public Map<QName, String> getAttrMap() {
return attrMap;
}
}
}
I try to run this code in Java 1.6 windows and gives the correct answer:
0
1
à€
When I try to run this code in IBM java 1.6 CentOS gives the wrong answer:
0
1
à €
Why the unmarshalling instruction doesn't convert correctly the à (even èéìòù...)?
If your input is actually a String I'd recommend passing that directly to the Unmarshaller, wrapped in a StringReader instead of trying to produce an InputStream from it. It's less error prone.
Try this (see code snippet below). Then you don't have to worry about whether your code specifies the correct encoding or does the character to byte conversion correctly for that encoding.
String xmlString = "<Grid><IO/><Changes><I id=\"0\" Changed=\"1\" STT=\"à€\"/></Changes></Grid>";
InputSource is = new InputSource(new StringReader(xmlString));
Marshal obj = (Marshal) unmarshaller.unmarshal(is);
Related
I am new to Restful W-S.I am trying to make basic web-service.I am unable to pass XML content (I am able to pass when I change it to plain text successfully)
package com.controller;
import javax.validation.constraints.NotBlank;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.pojo.Student;
#RestController
public class Controllers {
#RequestMapping(value="/hi",method=RequestMethod.POST,consumes=MediaType.TEXT_PLAIN_VALUE,produces=MediaType.APPLICATION_XML_VALUE)
public String hello(#RequestBody String std) {
System.out.println(std);
return "Response";
}
}
package com.pojo;
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(name="student")
#XmlAccessorType(XmlAccessType.FIELD)
public class Student {
#XmlElement(name="str")
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
Client-
package com.me.app;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.client.RestTemplate;
import com.pojo.Student;
#SpringBootApplication
#ComponentScan(basePackageClasses=com.controller.Controllers.class)
public class App {
public static void main(String args[])
{
SpringApplication.run(App.class, args);
getEmployees();
}
private static void getEmployees()
{
System.out.println("starting");
final String uri = "http://localhost:8005/hi";
Student std = new Student();
std.setStr("Something");
String s=jaxbObjectToXML(std);
System.out.println(s);
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.postForObject(uri, s, String.class);
System.out.println(result);
}
private static String jaxbObjectToXML(Student std) {
String xmlString = "";
try {
JAXBContext context = JAXBContext.newInstance(Student.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML
StringWriter sw = new StringWriter();
m.marshal(std, sw);
xmlString = sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlString;
}
}
Can anyone help me in passing content in XML.In the above scenario,I am able to pass text as content and its working fine.
Thanks in advance!
Try adding m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); Hope this helps.
i fetched the defect url:
String defectUrl = conn.buildEntityCollectionUrl("defect");
defectUrl += "/98";
Map<String, String> requestHeaders = new HashMap<String, String>();
requestHeaders.put("Accept", "application/xml");
Response res = conn.httpGet(defectUrl, null, requestHeaders);
then converted into Entity:
String postedEntityReturnedXml = res.toString();
Entity entity = EntityMarshallingUtils.marshal(Entity.class,postedEntityReturnedXml);
than change the field value:
List<Field> fields = entity.getFields().getField();
for (Field f : fields) {
if (f.getName().equalsIgnoreCase("id"))
{
int i=f.hashCode();
System.out.println(i);
f.getValue().clear();
f.setName("");
}
}
now trying to convert it to xml formate again:
String xml = EntityMarshallingUtils.unmarshal(org.eclipse.jetty.server.Response.class,**fields**);
System.out.println(xml);
throwing error as object fields should not be there and not able to get what should i put in place of fields?
my EntityMarshallingUtils class is like:
package org.hp.qc.web.restapi.docexamples.docexamples.infrastructure;
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.Marshaller;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
//import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class EntityMarshallingUtils {
private EntityMarshallingUtils() {}
#SuppressWarnings("unchecked")
public static <T> T marshal(Class<T> c, String xml) throws JAXBException {
T res;
if (c == xml.getClass()) {
res = (T) xml;
}
else {
JAXBContext ctx = JAXBContext.newInstance(c);
Unmarshaller marshaller = ctx.createUnmarshaller();
res = (T) marshaller.unmarshal(new StringReader(xml));
}
return res;
}
#SuppressWarnings("unchecked")
public static <T> String unmarshal(Class<T> c, Object o) throws Exception {
JAXBContext ctx = JAXBContext.newInstance(c);
Marshaller marshaller = ctx.createMarshaller();
StringWriter entityXml = new StringWriter();
marshaller.marshal(o, entityXml);
String entityString = entityXml.toString();
return entityString;
}
}
AnyOne who can help me on this?
This is my first post on Stack, so if there is something wrong, be patient ...
Ok, my question is how can I write an XML attribute with value. The result would be something like this:
<GroupAttribute>
<Attribute name = "Color"> Pink </Attribute>
.....
</GroupAttribute>
I tried this:
Element attribute = doc.createElement ("attribute");
groupAttribute.appendChild (attribute);
attribute.setAttribute ("attributeType" p.attributeColor);
groupAttribute.appendChild (getCompanyElements (doc, attribute, "attribute", p.attributeColor));
But it does not work.. the result is:
<GroupAttribute>
<Attribute> Pink </Attribute>
.....
</GroupAttribute>
the setAttribute is missing ...
What am I doing wrong?
Here the code:
import com.opencsv.*;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
*
* #author Mike
*/
public class prueba {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
List<Producto> prods = new ArrayList<Producto>();
try {
CSVReader reader;
reader = new CSVReader(new FileReader("C:\\Temp\\feeds\\Product_Prueba.csv"), ';');
String[] nextLine;
try {
while ((nextLine = reader.readNext()) != null) {
// nextLine[] is an array of values from the line
//System.out.println(Arrays.toString(nextLine));
//Lee
Producto p;
p = new Producto();
p.attributeColor = "Pink";
prods.add(p);
}
} catch (IOException ex) {
Logger.getLogger(prueba.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(prueba.class.getName()).log(Level.SEVERE, null, ex);
}
xeraXML(prods);
}
static void xeraXML(List<Producto> ps) {
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
try {
icBuilder = icFactory.newDocumentBuilder();
Document doc = icBuilder.newDocument();
Element mainRootElement = doc.createElement("productRequest");
doc.appendChild(mainRootElement);
for (Iterator<Producto> i = ps.iterator(); i.hasNext();) {
Producto p;
p = i.next();
mainRootElement.appendChild(getProductElement(doc, p));
}
// output DOM XML to console
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult console = new StreamResult(System.out);
//StreamResult out = new StreamResult("C:\\Temp\\results\\resultado.xml");
transformer.transform(source, console);
//transformer.transform(source, out);
} catch (Exception e) {
e.printStackTrace();
}
}
private static Element getProductElement(Document doc /*String localizedFor,*/, Producto p) {
Element groupAttribute = doc.createElement("groupAttribute");
Element attribute = doc.createElement("attribute");
groupAttribute.appendChild(attribute);
attribute.setAttribute("attributeType", p.attributeColor);
groupAttribute.appendChild(getElements(doc, attribute, "attribute", p.attributeColor));
return groupAttribute;
}
private static Node getElements(Document doc, Element element, String name, String value) {
Element node = doc.createElement(name);
node.appendChild(doc.createTextNode(value));
return node;
}
}
And here the Producto class:
public class Producto {
public String attributeColor;
}
I just wanted to add the comment but am writing it as an answer since I don't have that privilege yet. I was looking to add the attribute to the xml node and I came across this post.
dependency = dom.createElement("dependency");
dependency.setAttribute("type", "value");
dependencies.appendChild(dependency);
I added the child after setting the attribute.
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.
I have java code and i'm trying to parse it and store it as XML file on my PC using JAXB but i have a marshaling exception:
Exception in thread "main" javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an #XmlRootElement annotation]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:103)
at xml.ConfList.addToList(ConfList.java:29)
at xml.Tester.work(Tester.java:34)
at xml.Tester.main(Tester.java:16)
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an #XmlRootElement annotation
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)
at com.sun.xml.internal.bind.v2.runtime.LeafBeanInfoImpl.serializeRoot(LeafBeanInfoImpl.java:126)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
... 5 more
Java Result: 1
BUILD SUCCESSFUL (total time: 9 seconds)
The JAXB code i'm using :
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class ConfList {
private static final String fileName = "Source.xml";
List<String> xmlConfList;
private Object object;
public ConfList(Object object){
this.object = object;
}
public void addToList() throws IOException, JAXBException {
File file = new File(fileName);
JAXBContext jaxbContext = JAXBContext.newInstance(XmlConf.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(object, file); // i got the exception here
jaxbMarshaller.marshal(object, System.out);
}
}
The main class i use:
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.SAXException;
public class Tester{
public static void main (String [] args) throws XPathExpressionException, IOException, ParserConfigurationException, SAXException, TransformerException, JAXBException{
work();
}
public static void work () throws IOException, ParserConfigurationException, SAXException, XPathExpressionException, TransformerException, JAXBException{
String surl = "http://api.worldweatheronline.com/free/v1/weather.ashx?q=Cairo&format=xml&num_of_days=1&key=wd63kxr294rcgvbynhaf2z4r";
XmlSource xml = new XmlSource(surl);
xml.validate();
xml.load();
ArrayList<String> paths = xml.getAllPaths();
for(String path : paths){
System.out.println(path);
}
ConfList v = new ConfList(xml.getXml());
v.addToList();
}
}
The XmlConf Class :
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "XmlSource")
public class XmlConf {
private URL url;
private List<String> path = new ArrayList<String>();
private String urlp;
private Map<String, String> parameters;
private String host;
public URL getUrl() {
return url;
}
#XmlAttribute(name = "URL")
public void setUrl(URL url) {
this.url = url;
}
#XmlElement
public List<String> getPath() {
return path;
}
public void setPath(String path) {
this.path.add(path);
}
#XmlElement
public void setUrlPath(String urlp){
this.urlp = urlp;
}
public String getUrlPath(){
return urlp;
}
public void setParameters(Map<String, String> parameters){
this.parameters = parameters;
}
public Map<String, String> getParameters(){
return parameters;
}
public void setHostName(String host){
this.host = host;
}
public String getHostName(){
return host;
}
}
Note that all (XmlSource class) methods are run correctly.
Below is some sample code that unmarshals some XML into an instance of XmlConf and then marshals it back to XML.
Demo
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(XmlConf.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum16762200/input.xml");
XmlConf xmlConf = (XmlConf) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(xmlConf, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XmlSource URL="http://www.example.com">
<parameters>
<entry>
<key>A</key>
<value>a</value>
</entry>
<entry>
<key>B</key>
<value>b</value>
</entry>
</parameters>
<path>foo</path>
<urlPath>bar</urlPath>
</XmlSource>