I'm working on a project in java but I need to create and xml from a list of Strings on this way:
1: "/data/user/firstname/John"
2: "/data/user/middlename/F"
3: "/data/user/lastname/Thomas"
and the expected result should be this one:
<data>
<user>
<firstname>John</firstname>
<middlename>F</middlename>
<lastname>Thomas</lastname>
</user>
<data>
does anyone know if it possible in java? Thank you!
Working example with plain Java, without frameworks:
package test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
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 java.io.File;
import java.util.Arrays;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
String a = "/data/user/firstname/John";
String b = "/data/user/middlename/F";
String c = "/data/user/lastname/Thomas";
// Create arrays from string and trim first empty space before first '/'
String [] arrayA = Arrays.copyOfRange(a.split("/"), 1, a.split("/").length);
String [] arrayB = Arrays.copyOfRange(b.split("/"), 1, b.split("/").length);
String [] arrayC = Arrays.copyOfRange(c.split("/"), 1, c.split("/").length);
Element parent = null;
for (int i = 0; i < arrayA.length; i++) {
// Append text to child nodes, do it at very end
if (i == arrayA.length - 1) {
Element element1 = (Element) document.getElementsByTagName(arrayA[i - 1]).item(0);
element1.appendChild(document.createTextNode(arrayA[i]));
Element element2 = (Element) document.getElementsByTagName(arrayB[i - 1]).item(0);
element2.appendChild(document.createTextNode(arrayB[i]));
Element element3 = (Element) document.getElementsByTagName(arrayC[i - 1]).item(0);
element3.appendChild(document.createTextNode(arrayC[i]));
break;
}
// if names are same, appending only one of them
if ((arrayA[i].equals(arrayB[i])) && (arrayA[i].equals(arrayC[i]))) {
System.out.println("true");
// create root node
if (i == 0) {
Element element = document.createElement(arrayA[i]);
document.appendChild(element);
parent = element;
System.out.println(document.toString());
} else {
Element element = document.createElement(arrayA[i]);
parent.appendChild(element);
parent = element;
System.out.println(document.toString());
}
// if node names at same levels are different, add all of them
} else {
System.out.println("false");
Element element1 = document.createElement(arrayA[i]);
Element element2 = document.createElement(arrayB[i]);
Element element3 = document.createElement(arrayC[i]);
parent.appendChild(element1);
parent.appendChild(element2);
parent.appendChild(element3);
}
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File("result.xml"));
transformer.transform(domSource, streamResult);
}
}
Output of this program:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><data><user><firstname>John</firstname><middlename>F</middlename><lastname>Thomas</lastname></user></data>
Or, write it to file, then, to last lines need to be:
StreamResult streamResult = new StreamResult(new File("result.xml"));
transformer.transform(domSource, streamResult);
Related
I have an XML file call it (FromThis.xml) with sample data see below:
I want to read from the file(FromThis.xml) , store the values in variable then use those variable while creating a second XML file(ToThis.xml).
Brief description of my scenario[ I will read values from XML file(FromThis.xml) first and store them in a variables. Then I will use the variables to update the second xml file which is (ToThis.xml .I later use this xml to create some JSON file in some specified format.) I have been working with this but later we need to send array of elements in (FromThis.xml). From my code below i can only get the first array element but i want to loop through the elements, store them and use it to create the second xml (ToThis.xml)
(FromThis.xml)
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Root>
<ankomstDato>2020-08-20</ankomstDato>
<planlagtAntallPerUndergruppe>
<element>
<antall>67</antall>
<kode>SLAKTEGRIS</kode>
</element>
<element>
<antall>4</antall>
<kode>UNGSAU</kode>
</element>
</planlagtAntallPerUndergruppe>
</Root>
(ToThis.xml) Below xml is what i currently get.
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
</array>
</map>
What i would like to get as the result is
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
<map>
<number key="antall">4</number>
<string key="kode">UNGSAU</string>
</map>
</array>
</map>
Below is my Code
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
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 javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.w3c.dom.Element;
//** */
public class SolutionXML2XmlFormat {
//Create Public Variables to store data
//**
public static String ankomstDato_value; //1
public static String[] planlagtAntallPerUndergruppe_antall_value = new String[6]; //
public static String[] planlagtAntallPerUndergruppe_kode_value = new String[6]; //
//+++
public void Xml2JavaObject(String FromThis){
//read the xml(TheXMLPath) and store values in variables
// Boolean and numbers should be having values for string use " " if empty
try {
File file = new File(FromThis);
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
document.getDocumentElement().normalize();
System.out.println("Root element :" + document.getDocumentElement().getNodeName());
System.out.println("------------------------ \n");
//1 . ankomstDato
String ankomstDato = document.getElementsByTagName("ankomstDato").item(0).getTextContent();
ankomstDato_value = ankomstDato;
//end ankomstDato
NodeList planlagtAntallPerUndergruppe= document.getElementsByTagName("planlagtAntallPerUndergruppe");
for (int temp = 0; temp < planlagtAntallPerUndergruppe.getLength(); temp++) {
Node nNode = planlagtAntallPerUndergruppe.item(temp);
System.out.println("\n Current Elements :" + planlagtAntallPerUndergruppe.getLength());
System.out.println("\n No. of Element :" + temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String element18 = eElement.getElementsByTagName("antall").item(0).getTextContent();
planlagtAntallPerUndergruppe_antall_value[temp] = element18;
String element19 = eElement.getElementsByTagName("kode").item(0).getTextContent();
planlagtAntallPerUndergruppe_kode_value[temp] = element19;
}
}
} catch (Exception e) {
e.printStackTrace();
}
//Call method to write values
Write2XMLfile();
}
public void Write2XMLfile(){
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
try {
//
String filepath = "E:/utils/Tothis.xml";
//
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
// 1. ankomstDato
Node ankomstDato = (Node) xpath.evaluate("(/map/string[#key='ankomstDato'])[1]", doc, XPathConstants.NODE);
ankomstDato.setTextContent(ankomstDato_value );
// End ankomstDato
//2. planlagtAntallPerUndergruppe **************************
System.out.println("\n This is second" );
Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODE);
if(null != planlagtAntallPerUndergruppe) {
NodeList nodeList = planlagtAntallPerUndergruppe.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
//System.out.println("\n");
if(nod.getNodeType() == Node.ELEMENT_NODE){
NodeList arrayElements_18 = (NodeList) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODESET);
//System.out.println("\n number of elements" + arrayElements_18.getLength());
for (int j = 0; j < arrayElements_18.getLength(); j++) {
//. antall
Node antall = (Node) xpath.evaluate("(/map/array/map/number[#key='antall'])[1]", doc, XPathConstants.NODE);
antall.setTextContent(planlagtAntallPerUndergruppe_antall_value[j]);
// end antall
//. kode
Node kode = (Node) xpath.evaluate("(/map/array/map/string[#key='kode'])[1]", doc, XPathConstants.NODE);
kode.setTextContent(planlagtAntallPerUndergruppe_kode_value[j]);
//System.out.println("\n\n antall: " + planlagtAntallPerUndergruppe_antall_value[j]);
// end kode
}
}
}
}
// end array planlagtAntallPerUndergruppe
// 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(filepath));
transformer.transform(source, result);
System.out.println("Done Updating The Api_XML_Format.xml");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
} catch (XPathExpressionException xee) {
xee.printStackTrace();
}
}
}
as per the given code, planlagtAntallPerUndergruppe NodeList size is a one. because you select the <planlagtAntallPerUndergruppe> element.
NodeList planlagtAntallPerUndergruppe = document.getElementsByTagName("planlagtAntallPerUndergruppe");
hence, in the for loop, declared arrays collect the first <element> values only from FromThis.xml file.
<element>
<antall>67</antall>
<kode>SLAKTEGRIS</kode>
</element>
Solution
get the <element> NodeList into planlagtAntallPerUndergruppe as follows,
NodeList planlagtAntallPerUndergruppe = document.getElementsByTagName("element");
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;
}
}
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();
}
}
}
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.
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.