Create XML file based on user input - java

Extreme Java newb...I am trying to create a program that will take user input and build an XML file based on input from the user. This file is used by a contact center platform to identify retail locations based on caller ID. The XML structure looks like this:
<StoreList>
<Store str_callingnumber="1234567890">
<Number>Store1000</Number>
<Street>123 USA BLVD</Street>
<City>Nashville, TN 37211</City>
<WUGID>1234</WUGID>
</Store>
</StoreList>
I want to prompt the user to enter the phone number, store number, street, city, and WUGID, but keep getting an error about cannot convert String to Node. All of the other information I see on here is about parsing an existing XML file or creating one with DOM...but I haven't found any hints on creating one based on user input. Here is my code thus far...
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
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.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import java.util.Scanner;
public class CreateXmlFileDemo {
public static void main(String argv[]) {
Scanner sc = new Scanner(System.in);
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
// root element
Element rootElement = doc.createElement("StoreList");
doc.appendChild(rootElement);
// store element
Element store = doc.createElement("Store");
rootElement.appendChild(store);
// setting str_calling number attribute to store element
System.out.println("Enter the store phone number:");
String phone = sc.next();
Attr attr = doc.createAttribute("str_callingnumber");
attr.setValue(phone);
store.setAttributeNode(attr);
// store number element
Element storenumber = doc.createElement("Number");
System.out.println("Enter the store number:");
var number = sc.next();
store.appendChild(number);
//street address element
Element street = doc.createElement("Street");
System.out.println("Enter the street address:");
String address = sc.next();
street.appendChild(address);
Element zip = doc.createElement("City");
System.out.println("Enter the city, state, and ZIP code:");
String city = sc.next();
zip.appendChild(city);
Element wug = doc.createElement("WUGID");
System.out.println("Enter the WUGID:");
String wugid = sc.next();
wug.appendChild(wugid);
// 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("C:\\cars.xml"));
transformer.transform(source, result);
// Output to console for testing
StreamResult consoleResult = new StreamResult(System.out);
transformer.transform(source, consoleResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thank you anyone/everyone for taking the time to help me understand.

You seemed to have the right idea to start with, but got off track somewhere.
Basically, you're attempting to append a String value to a parent Node, but Node only accepts other Nodes as it children.
Instead, you need to apply the String value to the textContent of the Element you've already created and append the Element to the parent Node
Element storenumber = doc.createElement("Number");
System.out.println("Enter the store number:");
String number = sc.next();
//var number = sc.next();
//store.appendChild(number);
storenumber.setTextContent(number);
store.appendChild(storenumber);
Wash, rinse and repeat...

Related

evaluateXPath runs slow for repeating 1 XML Element in java

I have about 1,000,000 XML files and I am using XpathExpression with Java language to walk through the XML tags and get my considered data.
Imagine I have about 5000 tags for name, 5000 tags for family name, 5000 tags for age, and only 1 tag for date in each file. Now I want to repeat date tag to 5000 times too.
Blow code is runnable for XML files with Java programming with less than 20MB size, but I have files with more than 20MB size and it takes so many times to run and in some cases, I got Out of memory error in eclipse( I tried adding vmargs in the run configuration of Eclipse but it takes so much time and still so low.)
I am pretty sure there is a problem with my array for repeting date tag and it is not optimized, I really appreciate if you mind and have a look at my code, in addition I should say that i am newbie to java:
package TEST;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import java.util.Arrays;
public class Data {
//function started
public static void main(String[] args) throws Exception
{
//Get Files
String doc ="MyFileNew";
String dump="";
int number =200;
for (int i=1; i<=201; i++) {
number ++;
dump = doc+number;
String fileName= "/root/MyFiles/" + dump + ".xml";
Document document = getDocument(fileName);
;
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter pw = null;
//Using Document Builder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc1 = documentBuilder.parse(fileName);
/*******Get attribute values using xpath******/
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
try {
fw = new FileWriter("/root/Results/" + dump + ".txt");
bw = new BufferedWriter(fw);
pw = new PrintWriter(bw);
//Printing Name tags
pw.println( "Name"+ evaluateXPath(document, "/xml/item/item[#key='Name']/text()") );
//Counting Name tags
XPathExpression expr1 = xpath.compile("count(/xml/item/item[#key='Name']/)");
Number result1 = (Number) expr1.evaluate(doc1, XPathConstants.NUMBER);
int n = result1.intValue();
//Printing FamilyName tags
pw.println( "FamilyName: " + evaluateXPath(document, "/xml/item/item[#key='FamilyName']/text() \n") );
//Printing Age tags
pw.println( "Age: " + evaluateXPath(document, "/xml/item/item[#key='Age']/text() \n") );
//Repeating Date based on counting name tags
String[] strArray = new String[0];
for (int q=0; q<n;q++){
List<String> strArraytmp = evaluateXPath(document,"/xml/item/item[#key='date']/text()");
String[] strings = strArraytmp.stream().toArray(String[]::new);
strArray= Stream.of(strArray, strings ).flatMap(Stream::of).toArray(String[]::new);
}
pw.println("date: " + Arrays.toString(strArray));
System.out.println("this file goes to path:" + "/root/Results/Data/" + dump + ".txt");
pw.flush();
}
catch (IOException e)
{ e.printStackTrace(); } }
}
private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception
{
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
List<String> values = new ArrayList<>();
try
{
// Create XPathExpression object
XPathExpression expr = xpath.compile(xpathExpression);
// Evaluate expression result on XML document
NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
values.add(nodes.item(i).getNodeValue());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return values;
}
private static Document getDocument(String fileName) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(fileName);
return doc;
}
}

Having trouble formatting multiple nodes from a text to XML conversion in Java

I have a Java program which converts text files to XML. I need the following format:
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
</app:schedules>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:defaults>
The ending "/app:schedules" tag is not appending in the correct place
after the "/app:run" tag. The program is instead generating the following (which is not correct):
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:schedules>
</app:defaults>
The method in the java program is as follows: for this example i expilicitly added the text to each node to show what the data should be. - this method takes String args otherwise from the input text file.
public static void main(String[] args) {
String infile = args[0];
String outxml = args[1];
BufferedReader in;
StreamResult out;
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
try {
in = new BufferedReader(new FileReader(infile));
out = new StreamResult(outxml);
icBuilder = icFactory.newDocumentBuilder();
Document doc = icBuilder.newDocument();
Element mainRootElement = doc.createElementNS ("http://dto.cybermation.com/application", "app:appl");
mainRootElement.setAttribute("name", "TESTSHEDULE");
doc.appendChild(mainRootElement);
...
private static Node processTagElements3(Document doc, String "app:defaults") {
Element node1 = doc.createElement("app:schedules");
Element node2 = doc.createElement("app:run");
Element node3 = doc.createElement("app:schedule");
Element node4 = doc.createElement("app:rununit");
Element node5 = doc.createElement("app:agent");
node1.appendChild(node2);
node2.appendChild(node3);
node3.appendChild(doc.createTextNode("schedule frequency value"));
node1.appendChild(node4);
node4.appendChild(node5);
node5.appendChild(doc.createTextNode("agent hostname value"));
return node1;
}
I've tested this using different appenchild parameters between these nodes but ran up against a brick wall with formatiing this output. Any suggestions, advice on the best way to organize the node tag insertions is really appreciated. There could be somthing simple I am missing.
Note: I'm not an expert in for XML parsing in Java.
Just trying to stitch some example codes I got in my machine and see if that solves your problem. So here it is.
Example code:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.StringReader;
import java.io.StringWriter;\
public class test {
public static void main(String[] args) throws Exception {
String xml = "<app:defaults>\n" +
" <app:schedules>\n" +
" <app:run>\n" +
" <app:schedule>schedule frequency value</app:schedule>\n" +
" </app:run>\n" +
" </app:schedules>\n" +
" <app:rununit>\n" +
" <app:agent>agent hostname value</app:agent>\n" +
" </app:rununit> \n" +
" </app:defaults>";
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
NodeList errNodes = doc.getElementsByTagName("error");
if (errNodes.getLength() > 0) {
Element err = (Element)errNodes.item(0);
System.out.println(err.getElementsByTagName("errorMessage")
.item(0).getTextContent());
} else {
// success
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
System.out.println(writer.toString());
}
}
Output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<app:defaults>
<app:schedules>
<app:run>
<app:schedule>schedule frequency value</app:schedule>
</app:run>
</app:schedules>
<app:rununit>
<app:agent>agent hostname value</app:agent>
</app:rununit>
</app:defaults>
This code seems to be working as what you will expecting it to be. Give it a try and let me know whether the solution is okay.
I think the idea here is to use pre-baked Java APIs than writing our own parser. Because these APIs are generally more reliable since many others would be using it daily.
Things would be way easier if you had named your nodes with meaningful names (let's say runNode, etc), don't you think?
That being said, this is probably what you want:
Element defaultNode = doc.createElement("app:default");
Element schedulesNode = doc.createElement("app:schedules");
Element runNode = doc.createElement("app:run");
Element scheduleNode = doc.createElement("app:schedule");
Element rununitNode = doc.createElement("app:rununit");
Element agentNode = doc.createElement("app:agent");
defaultNode.appendChild(schedulesNode);
schedulesNode.appendChild(runNode);
runNode.appendChild(scheduleNode);
scheduleNode.appendChild(doc.createTextNode("schedule frequency value"));
defaultNode.appendChild(rununitNode);
rununitNode.appendChild(agentNode);
agentNode.appendChild(doc.createTextNode("agent hostname value"));
Note the defaultNode used.
Thanks all!
I decided to modify the script to accept file input as my arg - this works fine now and is a simpler solution:
public class test2 {
public static void main(String[] args) throws Exception {
File file = new File(args[0]);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try{
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream fis = new FileInputStream(file);
InputSource is = new InputSource(fis);
Document doc = builder.parse(is);
NodeList errNodes = doc.getElementsByTagName("error");
if (errNodes.getLength() > 0) {
Element err = (Element)errNodes.item(0);
System.out.println(err.getElementsByTagName("errorMessage").item(0).getTextContent());
} else {
// success
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
System.out.println(writer.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Dynamically insert an XML Element into a text node

I'm writing a program in Java where the ultimate goal is to create an XML file from user inputs.
I'm able to predict where almost all of the elements need to be, with one exception.
Any one sentence the user inputs is put into its own Callout tag:
<Callout>The user entered some text.</Callout>
If the sentence contains the phrase "User Guide", the program needs to automatically surround those two words with this XML tag:
<BookTitle></BookTitle>
For example, the initial tag looks like this:
<Callout>Save the User Guide</Callout>
The end result should be:
<Callout>Save the <BookTitle>User Guide</BookTitle>.</Callout>
Note that the term "User Guide" could appear in any location within the "Callout" tag.
I'm not sure how to dynamically add a tag into the middle of a text node. Is that even possible? I tried the solution found here (Convert String XML fragment to Document Node in Java)
but to no avail. I'm using org.w3c.dom to create the elements, nodes, etc.
Don't know exactly how you are constructing your XML document, I assumed the use of some kind of DOM.
This is a VERY simple example of a proof-of-concept. It borrows very heavily from library code, so it may be a little bloated in places, but the basic idea should be reasonable...
Basically, it searches a String for a given token (User Guide) in this case and splits the original text around it, appending #text nodes and <BookTitle> nodes appropriately...
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
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.Text;
public class Main {
public static final String BOOK_TITLE = "User Guide";
public static void main(String[] args) {
Document doc = null;
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = doc.createElement("root");
doc.appendChild(root);
// Create callout node...
Element callOut = doc.createElement("CallOut");
// Get the user input...
String text = "This is an example of a User Guide for you to read";
// Does it contain our marker...?
if (text.contains(BOOK_TITLE)) {
// While the text contains the mark, continue looping...
while (text.contains(BOOK_TITLE)) {
// Get the text before the marker...
String prefix = text.substring(0, text.indexOf(BOOK_TITLE));
// Get the text after the marker...
text = text.substring(text.indexOf(BOOK_TITLE) + BOOK_TITLE.length());
// If there is text before the marker, append it to the call out node
if (prefix.length() > 0) {
Text textNode = doc.createTextNode(prefix);
callOut.appendChild(textNode);
}
// Append the book title node...
Element bookTitle = doc.createElement("BookTitle");
bookTitle.setTextContent(BOOK_TITLE);
callOut.appendChild(bookTitle);
}
// If there is any text remaining, append it to the call out node...
if (text.length() > 0) {
Text textNode = doc.createTextNode(text);
callOut.appendChild(textNode);
}
} else {
// No marker, append the text to the call out node..
Text textNode = doc.createTextNode(text);
callOut.appendChild(textNode);
}
// This will dump the result for you to test....
root.appendChild(callOut);
ByteArrayOutputStream baos = null;
OutputStreamWriter osw = null;
try {
baos = new ByteArrayOutputStream();
osw = new OutputStreamWriter(baos);
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");
DOMSource domSource = new DOMSource(doc);
StreamResult sr = new StreamResult(osw);
tf.transform(domSource, sr);
osw.flush();
baos.flush();
System.out.println(new String(baos.toByteArray()));
} finally {
try {
baos.close();
} catch (Exception exp) {
}
}
} catch (IOException | TransformerException | ParserConfigurationException ex) {
ex.printStackTrace();
}
}
}
People will have different approaches to dealing with XML manipulations. The variety of answers to this question is proof enough of this. While using regex and raw text manipulation might be good for one off fixes and hacks if you want a good and maintainable solution you should use an XML API.
My example below does what is asked, however it should be noted that I didn't check for any pathological inputs like ("" as the search string) or deal with XML namespaces. Those things can be added easily enough.
See comments in the code for description of how it works.
Input (test.xml):
<Callouts>
<Callout>Save the User Guide.</Callout>
</Callouts>
Program
package com.stackoverflow._18774666;
import java.net.URL;
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.NodeList;
import org.w3c.dom.Text;
public class InsertElementInTextNode {
/**
* Replace text content of child text nodes of a parent element that
* matches a search string. The text is replace by an element named with the
* given name and has it's text content set equal to the search string.
*
* #param parent
* The element to search child text nodes of.
* #param elementName
* The name of the element to insert.
* #param text
* The text to replace with an element with same text content.
*/
public static void replaceTextWithElement(Element parent, String elementName, String text){
NodeList children = parent.getChildNodes();
Text cursor;
Element insertedElement;
int index;
/* Iterate children of the given element. */
for(int i = 0; i < children.getLength(); i++ ){
/* Check if this child is a text node. Ignore otherwise. */
if(children.item(i) instanceof Text){
cursor = (Text) children.item(i);
/* If the entire text node is equal to the search string,
* then we can replace it directly. Else we have split it.*/
if(text.equals(cursor.getData())){
/* Replace the text node with an element */
insertedElement = parent.getOwnerDocument().createElement(elementName);
insertedElement.setTextContent(text);
parent.replaceChild(insertedElement, cursor);
} else {
/* Check to see if the search string exists in this text node. Ignore otherwise.*/
index = cursor.getData().indexOf(text);
if(index != -1){
/* Replace the matched substring with an empty string.*/
cursor.replaceData(index, text.length(), "");
/* Create element to be inserted, and set the text content. */
insertedElement = parent.getOwnerDocument().createElement(elementName);
insertedElement.setTextContent(text);
/* Split the text node and insert the element in the middle. */
parent.insertBefore(insertedElement, cursor.splitText(index));
}
}
}
}
}
public static void main(String[] args) throws Exception {
/* Location of our XML document. */
URL xmlSource = InsertElementInTextNode.class.getResource("test.xml");
/* Parse with DOM in to a Document */
Document xmlDoc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(xmlSource.openStream());
/* Find our interesting elements. */
NodeList nodes = xmlDoc.getElementsByTagName("Callout");
/* Iterate through our interesting elements and check their content.*/
Element cursor;
for(int i = 0; i < nodes.getLength(); i++ ){
if(nodes.item(i) instanceof Element){
cursor = (Element) nodes.item(i);
replaceTextWithElement(cursor, "BookTitle", "User Guide");
}
}
/* Setup to output result. */
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
/* Printing result to stdout. */
transformer.transform(new DOMSource(xmlDoc),
new StreamResult(System.out));
}
}
Output (stdout):
<Callouts>
<Callout>Save the <BookTitle>User Guide</BookTitle>.</Callout>
</Callouts>
first get the user input and compare it to user guide, if it's true then surround it with title.
String UserInput = null;
UserInput = #getUserType.toString();
if(UserInput.equals("User Guide")){
UserInput = "<BookTitle>"+UserInput+"<BookTitle>";
}else{
//do things if it's false not User Guide
}
public static void main(String[] args) {
String str = "This is my User Guide dude";
boolean bTest = str.contains("User Guide");
if (bTest) {
int index1 = str.indexOf("User Guide");
String sub = str.substring(index1, index1 + 10);
sub = "<BookTitle>" + sub + "</BookTitle>";
String result = str.replace("User Guide", sub);
System.out.println(result);
}
}
OUTPUT:
This is my <BookTitle>User Guide</BookTitle> dude
I think this will point you in the right direction at least.

Reading the output from console and print in XML file in java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How could I read Java Console Output into a String buffer
I know how to read input from user and put it on XML file.Here is the sample:
from http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class WriteXMLFile {
public static void main(String argv[]) {
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("C:\\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();
}
}
}
but my question is how to read the output from the console in java and print it in specified XML file.
I am not sure what exactly you mean by "reading the output from the console" but you can intercept calls to System.out by using http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#setOut%28java.io.PrintStream%29.
If you elaborate more on what you are trying to do I can be more specific.

DOM parser in java not encoding quotes in UTF-8

I am trying to use the code available from this tutorial :http://www.mkyong.com/java/how-to-create-xml-file-in-java-dom/
I've pasted the code below as well, the problem it seems to encode all the predef characters <,> and & etc. but not single or double quotes (" and '). I'd really appreciate a fix. Also the code below has an edit to make the resultant xml appear properly formatted
More specifically:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class WriteXMLFile {
public static void main(String argv[]) {
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();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("C:\\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();
}
}
}
I think your code works fine. Put a double quote in an attribute value and see what happens.
Read section 2.4 of the XML specification. Production 14 of the grammar
[14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
tells you that character data can be any (valid XML) character except '<' and '&' (or the ']]>' sequence). It is not strictly necessary to escape '>', although recommended.

Categories