Java: Append to XML File [duplicate] - java

This question already has answers here:
Modify the content of a file using Java
(6 answers)
Closed 5 years ago.
I have the below code that writes to an xml file, the problem that I am having is that it creates a new file every time i write to it and overwrites the other data saved in the file. I am looking for a solution that would append to the existing file instead. How do I modify this code to append to the file each time instead of overwrite? Also, I am using the netbeans IDE to run this program.
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.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
public class WriteXMLFile {
public static void main() throws ParserConfigurationException,SAXException,Exception
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();//
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();//
Document doc = docBuilder.newDocument();// this is difrent
Element rootElement = doc.createElement("Contacts");//
doc.appendChild(rootElement); // this is difrent
// staff elements
Element Contact1 = doc.createElement("Contact1");
rootElement.appendChild(Contact1);
// set attribute to staff element
Contact1.setAttribute("id","1");
// firstname elements
Element firstname = doc.createElement("Name");
firstname.appendChild(doc.createTextNode(EmailFrame.name.getText()));
Contact1.appendChild(firstname);
//Email Element
Element email = doc.createElement("Email");
email.appendChild(doc.createTextNode(EmailFrame.email.getText()));
Contact1.appendChild(email);
// phone element
Element phone= doc.createElement("Phone");
phone.appendChild(doc.createTextNode(EmailFrame.phone.getText()));
Contact1.appendChild(phone);
//id element
Element id = doc.createElement("ID");
id.appendChild(doc.createTextNode(EmailFrame.id.getText()));
Contact1.appendChild(id);
try{
// 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:/Users/steve/Desktop/xmlemail/Email.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
}
catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}

What you need to do is read the contents of the xml file into an object first before writing, then append your new content to your object then write your object to the xml file
Look at this resource for reading an xml file it should help
https://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/

Related

Save the exported CSV file via Java

I have managed to export a CSV file using JAVA. Now, I want those CSV files to be saved because I noticed that if I do not manually save them, I cannot use my CSV files to connect with other programs and do things with them. Please take a look, and help me out. Thank you !!!
package edi.converter.main;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import edi.converter.outbound.sqlserver.OutboundProcess;
public class MainAppConverter {
public static void main(String[] args) throws Exception {
Result outputTarget = new StreamResult(new File("C:\\Users\\Khoa S Tran\\Desktop\\out.csv"));
Result outputTarget1 = new StreamResult(new File("C:\\Users\\Khoa S Tran\\Desktop\\out1.csv"));
File stylesheet = new File("C:\\Users\\Khoa S Tran\\Desktop\\style.xsl");
File xmlSource = new File("C:\\Users\\Khoa S Tran\\Desktop\\data.xml");
File xmlSource1 = new File("C:\\Users\\Khoa S Tran\\Desktop\\data1.xml");
// it is noted that it is impossible/challlenging to combine xml files then export them to one csv
//suggestion will be concatenate multiple csv files together
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
Document document1 = builder.parse(xmlSource1);
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(document);
Source source1 = new DOMSource(document1);
transformer.transform(source, outputTarget);
//OutboundProcess.trytoExportSQL();
transformer.transform(source1, outputTarget1);
}
}
Bottom line is I have 2 XML files, I want to read them, combine them together, and export them to 1 single CSV file.
In case you might wonder where I can find the source code for concatenating 2 CSV's: How to merge multiple csv files into one in Java

Problem with inserting/appending comment before root node and after prolog with org.w3c.dom

Im trying to insert a comment with syntax version information before the first node of an xml document but for some reason it always gets appended after the last element. I cant use other libraries like XStream and such.
I have already tried to do this via the append and the insertBefore method but both of them yield the same result. Is it possible to do this just with the plain Document, Comment and Node or do I have to use a Transformer?
Document doc = XmlDocumentUtil.createDocument();
//Create root node
Node rootNode = doc.createElement(NODE_DATA_CONFIGURATION);
doc.appendChild(rootNode);
//Create syntax identification comment
Comment syntaxIdentification = doc.createComment(writeSyntaxIdentificationQE);
doc.insertBefore(syntaxIdentification, rootNode);
//Create revision information
Element modificationNumber = doc.createElement("modificationNumber");
modificationNumber.setTextContent(String.valueOf(configTable.getModificationNumber()));
rootNode.appendChild(modificationNumber);
Element modificationTime = doc.createElement("modificationTime");
modificationTime.setTextContent(configTable.getModificationTime());
rootNode.appendChild(modificationTime);
Element modifier = doc.createElement("modifier");
modifier.setTextContent(configTable.getModifier());
rootNode.appendChild(modifier);
for (...) {
... some data generation
}
What I get:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<DataConfiguration>
<modificationNumber>2</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
<modifier>testuser</modifier>
<someData idxFrom="4" idxTo="9"
signalName="1" signalOffset="273.15" signalTemplate="asdf" skip="Y"/>
</DataConfiguration>
<!--SyntaxIdentification: 1.0-->
What I need:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--SyntaxIdentification: 1.0-->
<DataConfiguration>
<modificationNumber>2</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
<modifier>testuser</modifier>
<someData idxFrom="4" idxTo="9"
signalName="1" signalOffset="273.15" signalTemplate="asdf" skip="Y"/>
</DataConfiguration>
To me your code seems good overall. Seems like you are missing only text nodes.
Here is full working code.
package xml;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
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.*;
public class XMLComment {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
// Create root node
Node rootNode = doc.createElement("DataConfiguration");
doc.appendChild(rootNode);
// Create syntax identification comment
Comment syntaxIdentification = doc.createComment("SyntaxIdentification: 1.0");
doc.insertBefore(syntaxIdentification, rootNode);
// Create modificationNumber
Node modificationNumber = doc.createElement("modificationNumber");
Text mnText = doc.createTextNode("123456");
modificationNumber.appendChild(mnText);
// Create modificationTime
Element modificationTime = doc.createElement("modificationTime");
Text mtText = doc.createTextNode("2019-07-25 07:42:28.804 +0200");
modificationTime.appendChild(mtText);
rootNode.appendChild(modificationNumber);
rootNode.appendChild(modificationTime);
printXML(doc);
}
private static void printXML(Document doc) throws TransformerException {
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);
}
}
It will output, close to what exactly you are looking for.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--SyntaxIdentification: 1.0--><DataConfiguration>
<modificationNumber>123456</modificationNumber>
<modificationTime>2019-07-25 07:42:28.804 +0200</modificationTime>
</DataConfiguration>
Hope it helps.

How I need to get tag name of sub child in xml by comparing the attribute value and given string value using Java?

I have a xml file. I need to get the sub child tag of the parent tag (Body) in xml file using Java. First I need to use DOM for reading an element
and get xml file from my local machine drive. I have one String varaible (Sring getSubChildValue = "181_paragraph_13") and I need to compare the value
with each and every attribute Value in the Xml file. If the given Value may be in sub child tag,I cont able to get a Value.
what I need to do for compare the String variable and with Xml File
What I need to do for print the Tag name if the String value is equal to any attrinbute Value.
Example: (P) Tag is the sub child of Tag (Body) which contain the given String Value. So I need to get tag name P.
How to avoid the Hard coding the sub-child Name to get the solution?
Example XML file:
<parent>
<Body class="student" id="181_student_method_3">
<Book class="Book_In_School_11" id="181_student_method_11"/>
<subject class="subject_information " id="181_student_subject_12"/>
<div class="div_passage " id="181_div_method_3">
<p class=" paragraph_book_name" id="181_paragraph_13">
<LiberaryBook class="Liberary" id="181_Liberary_9" >
<Liberary class="choice "
id="Liberary_replace_1" Uninversity="University_Liberary_1">
Dubliners</Liberary>
<Liberary class="choice "
id="Liberary_replace_2" Uninversity="University_Liberary_2">
Adventure if sherlock Holmes</Liberary>
<Liberary class="choice "
id="Liberary_replace_3" Uninversity="University_Liberary_3">
Charlotte’s Web</Liberary>
<Liberary class="choice "
id="Liberary_replace_4" Uninversity="University_Liberary_4">
The Outsiders</Liberary>
</LiberaryBook>
</p>
</div>
</Body>
</parent>
Example Java code:
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
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.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class PerfectTagChange {
public static void main(String[] args) {
String filePath = "/xmlfile/Xml/check/sample.xml";
File xmlFile = new File(filePath);
DocumentBuilderFactory
dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
Element root = doc.getDocumentElement();
changeValue(root,doc);
doc.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/xmlfile/Xml/check/Demo.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
System.out.println("XML file updated successfully");
} catch (SAXException | ParserConfigurationException | IOException | TransformerException e1) {
e1.printStackTrace();
}
}
//This Method is used to check which attribute contain given string Value : Hard code parent tag, But no other tag.
private static void changeValue(Node someNode,Document doc) {
Sring getSubChildValue = "181_paragraph_13"
NodeList childs = someNode.getChildNodes();
for (int in = 0; in < childs.getLength();) {
Node child = childs.item(in);
if (child.getNodeType() == Document.ELEMENT_NODE) {
if (child.getNodeName().equalsIgnoreCase("Body") ) {
//If I hard code the ID here on getNamedItem("id"),
If the attribute Name got Changed from ID to Name
it will be in problem.
//3.What is the solution for solving the problem.
if(child.getAtrribute.getNamedItem("id").getNodeValue().equals(getSubChildValue)){
system.out.println(child.getAtrribute.getNamedItem("id").getNodeValue());
}
}
}
}
}
If you change your code to this:
private static void changeValue(Node someNode, Document doc, String searchString) throws Exception {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xPath.evaluate("//*[#*=\"" + searchString + "\"]",
doc.getDocumentElement(),
XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("Tagname: " + nodes.item(i).getNodeName());
}
}
you don't have the name of the attribute to be hardcoded.
EDIT:
Added searchString as parameter.

Setting attribute without prefix using Java DOM

Using Java DOM I'm trying to set an attribute for an element without the namespace before the attribute name.
So, what I need is:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
If I try to set the attribute as following element1.setAttributeNS("http://www.myschema.com", "attr1", value); I get an empty xmlns tag and additionaly a xmlns with prefix like the following:
<element1 attr1="value" xmlns="" xmlns:ns3="http://www.myschema.com">foo</element1>
If I try to set the attribute as following element1.setAttribute("xmlns:attr1", value); I get a prefix (xmlns) before my attribute name as shown here:
<element1 xmlns:attr1="value">foo</element1>
As for further information I create my elements as following:
Element element = dom.createElementNS("http://www.myschema.com", elemName);
element.appendChild(dom.createCDATASection("foo");
xmlElement.appendChild(element);
Let's look at your desired output again:
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
In this document, the following statements are true:
documentObject and element1 are in the http://www.myschema.com namespace.
The attribute attr1 is not in any namespace.
While elements whose names are not prefixed are going to be in whatever default namespace is in effect, attributes whose names are not prefixed are not in any namespaces. See the spec:
Default namespace declarations do not apply directly to attribute names; the interpretation of unprefixed attributes is determined by the element on which they appear.
So to obtain the output you desire, you should be able to just do:
element1.setAttribute("attr1", value);
Of course this all depends on the desired output being correct. If really attr1 must be in a namespace, then your desired output is incorrect.
Below code will produce output
<?xml version="1.0" encoding="UTF-8"?>
<documentObject xmlns="http://www.myschema.com">
<element1 attr1="value">foo</element1>
</documentObject>
Java Code
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 XMLTest {
public static void main(String[] args) throws ParserConfigurationException, TransformerException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element element = doc.createElementNS("http://www.myschema.com", "documentObject");
doc.appendChild(element);
Element element1 = doc.createElement("element1");
element.appendChild(element1);
element1.appendChild(doc.createTextNode("foo"));
Attr attr = doc.createAttribute("attr1");
attr.setValue("value");
element1.setAttributeNode(attr);
element.appendChild(element1);
// 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("testfile.xml"));
transformer.transform(source, result);
System.out.println("File saved!");
}
}

Overwriting an existing XML document in Java using dom parsers api

I would like to know how do I overwrite and existing element in Java using dom parser. for example, I have the file
I am trying to overwrite the element and replace it with the element
Thanks.
Algorithm is easy:
Read a file and parse it to XML document
Make any changes you want
Overwrite existing file with new content
See my example:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
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;
public class DomProgram {
public static void main(String[] args) throws Exception {
File xmlFile = new File("C:\\test.xml");
Document document = readXmlDocument(xmlFile);
makeChanges(document);
Transformer transformer = createXmlTransformer();
overwriteXmlFile(xmlFile, document, transformer);
}
private static void overwriteXmlFile(File xmlFile, Document document,
Transformer transformer) throws FileNotFoundException,
TransformerException {
StreamResult result = new StreamResult(new PrintWriter(
new FileOutputStream(xmlFile, false)));
DOMSource source = new DOMSource(document);
transformer.transform(source, result);
}
private static Transformer createXmlTransformer() throws Exception {
Transformer transformer = TransformerFactory.newInstance()
.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
return transformer;
}
private static void makeChanges(Document document) {
Element root = document.getDocumentElement();
root.setAttribute("test", "testvalue");
}
private static Document readXmlDocument(File xmlFile) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlFile);
return document;
}
}
Example XML file:
<note>
<to>Ebele</to>
<from>mykhaylo</from>
<heading>Reminder</heading>
<body>Read about problem before you ask ;)</body>
</note>
Also see:
Simple Java DOM XML Example
How To Read XML File In Java – (DOM Parser)

Categories

Resources