How to make an XML document downloadable without intermediate file storage? - java

I have an object which holds data of a person. When a user clicks on the download button the xml needs to be created by (person.dataitems) and after that user should have an option to download the file (like save file or open file)
I have written the code below which creates a xml file when the button is clicked however the file remains empty. I would like to know how I can write data to this file and then download.
response.setHeader( "Content-Disposition", "attachment;filename="+patient.getGivenName()+".xml");
try {
StringWriter r = new StringWriter();
String ccdDoc = r.toString();
ccdDoc = ccdDoc.replaceAll("<", "<");
ccdDoc = ccdDoc.replaceAll(""", "\"");
byte[] res = ccdDoc.getBytes(Charset.forName("UTF-8"));
response.setCharacterEncoding("UTF-8");
response.getOutputStream().write(res);
response.flushBuffer();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thanks.

You have to write into your StringWriter:
import java.io.*;
public class StringWriterDemo {
public static void main(String[] args) {
String s = "Hello World";
// create a new writer
StringWriter sw = new StringWriter();
// write portions of strings
sw.write(s, 0, 4);
sw.write(s, 5, 6);
// write full string
sw.write(s);
// print result by converting to string
System.out.println("" + sw.toString());
}
}
Do not do:
String ccdDoc = r.toString();
It only creates a copy of the r string. Then you are modifying the copy, but not at all the content of the StringWriter.
Do:
r.write("some content");
and to access the string contained by the writer, do:
String a_string = r.toString();
response.getOutputStream().write(a_string);
EDIT :
OK, so what you are asking is not so far from what you have in the link you provided, excepted that you have to write into a StringWriter instead of into a File.
This can be achieved this way:
1) Do build an xml document:
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("company");
doc.appendChild(rootElement);
// staff elements
Element staff = doc.createElement("Staff");
rootElement.appendChild(staff);
// set attribute to staff element
staff.setAttribute("id", "1");
// firstname elements
Element firstname = doc.createElement("firstname");
firstname.appendChild(doc.createTextNode("yong"));
staff.appendChild(firstname);
:
:
// Then write the doc into a StringWriter
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//initialize StreamResult with StringWriter object to save to string
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);
// Finally, send the response
byte[] res = xmlString.getBytes(Charset.forName("UTF-8"));
response.setCharacterEncoding("UTF-8");
response.getOutputStream().write(res);
response.flushBuffer();
The point here is to do:
StreamResult result = new StreamResult(new StringWriter());
instead of:
StreamResult result = new StreamResult(new File("C:\\file.xml"));
You tell me if there is still something unclear in this.

it's worked
byte[] res = xmlString.getBytes(Charset.forName("UTF-8"));
response.setCharacterEncoding("UTF-8");
response.setHeader( "Content-Disposition", "attachment;filename=archivo.xml");
response.getOutputStream().write(res);
response.flushBuffer();

Related

Indent xml read from httpservlet request body?

I am trying to read xml string from HttpServletRequest like this:
private String getPayload(HttpServletRequest httRequest, String contentType){
StringBuilder buffer = new StringBuilder();
String data = null, payload = null;
BufferedReader bufferedReader = null;
try {
bufferedReader = httRequest.getReader();
String line;
while ((line = bufferedReader.readLine()) != null) {
buffer.append(line);
}
data = buffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Payload data: " + data);
}
This gives me a string like:
<?xml version="1.0" encoding="UTF-8"?><sgn> <nev> <rep> <cin rn="cin227"> <ty>4</ty> <ri>R241</ri> <pi>R7</pi> <ct>2016-10-27T18:23:49</ct> <lt>2016-10-27T18:23:49</lt> <et>2016-11-27T18:23:49</et> <at>erer</at> <aa>name</aa> <st>17</st> <cs>88</cs> <con>Sid-Container-Element</con> </cin> </rep> <net>3</net> </nev> <sur>R7/R8</sur> <cr>C1</cr></sgn>
So it's not indented. I tried a couple of things to indent it, like:
XPathFactory xpathFactory = XPathFactory.newInstance();
// XPath to find empty text nodes.
XPathExpression xpathExp = xpathFactory.newXPath().compile(
"//text()[normalize-space(.) = '']");
NodeList emptyTextNodes = (NodeList)
xpathExp.evaluate(doc, XPathConstants.NODESET);
// Remove each empty text node from document.
for (int i = 0; i < emptyTextNodes.getLength(); i++) {
Node emptyTextNode = emptyTextNodes.item(i);
emptyTextNode.getParentNode().removeChild(emptyTextNode);
}
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);
So first removing empty spaces using xpath and then applying transformer. So this still not giving me proper output:
<?xml version="1.0" encoding="UTF-8"?><sgn >
<nev>
<rep>
<cin rn="cin227">
<ty>4</ty>
<ri>R241</ri>
<pi>R7</pi>
<ct>2016-10-27T18:23:49</ct>
<lt>2016-10-27T18:23:49</lt>
<et>2016-11-27T18:23:49</et>
<at>erer</at>
<aa>name</aa>
<st>17</st>
<cs>88</cs>
<con>Sid-Container-Element</con>
</cin>
</rep>
<net>3</net>
</nev>
<sur>R7/R8</sur>
<cr>C1</cr>
</sgn>
So it's not properly indenting it. I want proper indentation.
Anything I am doing wrong here ??

Retain escape character [" < etc..] while copying XML node - Java

I am creating target XML by copying source XML content. I am doing copy at node level.
Source XML has content with escape character which gets converted [$quot; to " etc...] while I create my target XML
Is there any way to retain original XML content.
Appreciate any help on this.
copyXmlFile("Workflow", "./Source.xml", "./Destination.xml");
private static void copyXmlFile(String xmlType, String objectSourceFile, String outfile) throws TransformerException {
//Get the DOM Builder Factory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//Get the DOM Builder
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
}
//document contains the complete XML as a Tree.
try {
File xmlFileContent = new File(objectSourceFile);
Document document = builder.parse(new FileInputStream(xmlFileContent));
// root elements
Document documentOut = builder.newDocument();
Element rootElementOut = documentOut.createElement(xmlType);
rootElementOut.setAttribute("xmlns", "http://soap.sforce.com/2006/04/metadata");
documentOut.appendChild(rootElementOut);
NodeList nodeList = document.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element) {
//Node copiedNode = documentOut.importNode(node, true);
//rootElementOut.appendChild(copiedNode);
rootElementOut.appendChild(documentOut.adoptNode(node.cloneNode(true)));
}
}
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(documentOut);
//StreamResult result = new StreamResult(new File(outfile));
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
//transformer.setOutputProperty(OutputKeys.METHOD, "xml");
//transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(source, result);
System.out.println("Escaped XML String in Java: " + writer.toString());
} catch (SAXException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

Cannot create XML Document from String

I am trying to create an org.w3c.dom.Document form an XML string. I am using this How to convert string to xml file in java as a basis. I am not getting an exception, the problem is that my document is always null. The XML is system generated and well formed. I wish to convert it to a Document object so that I can add new Nodes etc.
public static org.w3c.dom.Document stringToXML(String xmlSource) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream input = IOUtils.toInputStream(xmlSource); //uses Apache commons to obtain InputStream
BOMInputStream bomIn = new BOMInputStream(input); //create BOMInputStream from InputStream
InputSource is = new InputSource(bomIn); // InputSource with BOM removed
Document document = builder.parse(new InputSource(new StringReader(xmlSource)));
Document document2 = builder.parse(is);
System.out.println("Document=" + document.getDoctype()); // always null
System.out.println("Document2=" + document2.getDoctype()); // always null
return document;
}
I have tried these things: I created a BOMInputStream thinking that a BOM was causing the conversion to fail. I thought that this was my issue but passing the BOMInputStream to the InputSource doesn't make a difference. I have even tried passing a literal String of simple XML and nothing but null. The toString method returns [#document:null]
I am using Xpages, a JSF implementation that uses Java 6. Full name of Document class used to avoid confusion with Xpage related class of the same name.
Don't rely on what toString is telling you. It is providing diagnostic information that it thinks is useful about the current class, which is, in this case, nothing more then...
"["+getNodeName()+": "+getNodeValue()+"]";
Which isn't going to help you. Instead, you will need to try and transform the model back into a String, for example...
String text
= "<fruit>"
+ "<banana>yellow</banana>"
+ "<orange>orange</orange>"
+ "<pear>yellow</pear>"
+ "</fruit>";
InputStream is = null;
try {
is = new ByteArrayInputStream(text.getBytes());
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
System.out.println("Document=" + document.toString()); // always null
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.METHOD, "xml");
tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
ByteArrayOutputStream os = null;
try {
os = new ByteArrayOutputStream();
DOMSource domSource = new DOMSource(document);
StreamResult sr = new StreamResult(os);
tf.transform(domSource, sr);
System.out.println(new String(os.toByteArray()));
} finally {
try {
os.close();
} finally {
}
}
} catch (ParserConfigurationException | SAXException | IOException | TransformerConfigurationException exp) {
exp.printStackTrace();
} catch (TransformerException exp) {
exp.printStackTrace();
} finally {
try {
is.close();
} catch (Exception e) {
}
}
Which outputs...
Document=[#document: null]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<fruit>
<banana>yellow</banana>
<orange>orange</orange>
<pear>yellow</pear>
</fruit>
You can try using this: http://www.wissel.net/blog/downloads/SHWL-8MRM36/$File/SimpleXMLDoc.java

Do I need server code in order to edit server files remotely?

I have a web server with an xml file that at some point is going to hold the information for posts on the website. This is the xml's structure.
<?xml version="1.0" encoding="ISO-8859-1"?>
<posts>
<post>
<date>7/9/2013 6:44 PM</date>
<category>general</category>
<poster>elfenari</poster>
<title>Test Post</title>
<content>This is a test post for the website</content>
</post>
</posts>
I created an applet using swing in netbeans, with this as the code to create the xml from the UI objects in the applet.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(url.openStream());
Element root = doc.getDocumentElement();
Element ePost = doc.createElement("post");
Element eDate = doc.createElement("date");
eDate.setTextContent(time);
Element eCategory = doc.createElement("category");
eCategory.setTextContent(category);
Element eTitle = doc.createElement("title");
eTitle.setTextContent(title);
Element ePoster = doc.createElement("poster");
ePoster.setTextContent(poster);
Element eContent = doc.createElement("content");
eContent.setTextContent(post);
ePost.appendChild(eDate);
ePost.appendChild(eCategory);
ePost.appendChild(eTitle);
ePost.appendChild(ePoster);
ePost.appendChild(eContent);
root.appendChild(ePost);
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String xmlString = sw.toString();
OutputStream f0;
byte buf[] = xmlString.getBytes();
f0 = new FileOutputStream(url);
for(int i=0;i<buf .length;i++) {
f0.write(buf[i]);
}
f0.close();
buf = null;
} catch (TransformerException ex) {
Logger.getLogger(xGrep.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParserConfigurationException | SAXException | IOException ex) {
Logger.getLogger(xGrep.class.getName()).log(Level.SEVERE, null, ex);
}
}
I've done some research, and I think I need a java program on my server to accept the change to the xml, but I'm not sure how exactly to do that. Could you tell me what I need to edit the file on the server, and how to code something if I do need it?

Append to an XML file

I am writing some data to an XML file.
Here is the code:
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
// root elements
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("company");
doc.appendChild(rootElement);
// staff elements
Element staff = doc.createElement("Staff");
rootElement.appendChild(staff);
// set attribute to staff element
Attr attr = doc.createAttribute("id");
attr.setValue("1");
staff.setAttributeNode(attr);
// shorten way
// staff.setAttribute("id", "1");
// firstname elements
Element firstname = doc.createElement("firstname");
firstname.appendChild(doc.createTextNode("yong"));
staff.appendChild(firstname);
// lastname elements
Element lastname = doc.createElement("lastname");
lastname.appendChild(doc.createTextNode("mook kim"));
staff.appendChild(lastname);
// nickname elements
Element nickname = doc.createElement("nickname");
nickname.appendChild(doc.createTextNode("mkyong"));
staff.appendChild(nickname);
// salary elements
Element salary = doc.createElement("salary");
salary.appendChild(doc.createTextNode("100000"));
staff.appendChild(salary);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("file.xml"));
// Output to console for testing
// StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println("File saved!");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
This code writes the XML data to the "file.xml". If I already have a "file.xml" file, what is the best way to append the XML data to the file? Will I need to rewrite the whole above code, or is it easy to adapt the code?
Yes - you're dealing with DOM, so you have to have the whole file in memory. Alternative is StAX.
StreamResult result = new StreamResult(new File("file.xml"));
Check this line.
Replace the above line with this.
StreamResult result = new StreamResult(new FileOutputStream("file.xml", true));
By default the second parameter is false.
True means it will append to file, false means it will overwrite it.

Categories

Resources