Java overwriting files with stream result - java

I created a simple class to create an XML document.
However, if I call the method more than once while creating a document of the same name the file does not overwrite.
How could I make the class automatically overwrite existing files of the same name?
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.TransformerConfigurationException;
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 XMLCreater {
public static void CreateXMLDoc(String name, String root, String[] elements, String[] children) throws TransformerConfigurationException {
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement(root);
doc.appendChild(rootElement);
for (int i = 0; i < elements.length; i ++) {
Element element = doc.createElement(elements[i]);
element.appendChild(doc.createTextNode(children[i]));
rootElement.appendChild(element);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
File dir = new File(System.getProperty("user.dir"));
StreamResult result = new StreamResult(new File(dir + "\\XML\\" + name + ".xml"));
transformer.transform(source, result);
}
catch(ParserConfigurationException pce){
pce.printStackTrace();
} catch(TransformerException tfe) {
tfe.printStackTrace();
}
}
}

I executed your code with the following statements:
public static void main (String[] args)
{
XMLCreater x = new XMLCreater();
String[] s = {"A","B","C"};
try
{
x.CreateXMLDoc("k","root",s,s);
x.CreateXMLDoc("k","root",s,s);
x.CreateXMLDoc("fakih","root",s,s);
}
catch (TransformerConfigurationException exception)
{ exception.printStackTrace(); }
}
And it nicely overwrites the existing files, no problems about overwriting, check it yourself.

I'll be honest here... I'm not able to replicate your problem. It works fine for me when I run this program multiple times in a for loop. Are you sure you didn't accidentally open the result file, thus locking it, before running your program?
If you are concerned of having multiple threads running your program at the same time, perhaps you can apply a synchronized block to prevent two threads trying to write the same file, like this:-
...
synchronized (XMLCreater.class) {
StreamResult result = new StreamResult(new File(dir + "\\XML\\" + name + ".xml"));
transformer.transform(source, result);
}

Related

Read from folder and update the XML tag value

I have a folder("Container") inside this i have some .txt files which actually contains XML. All files have a common element <Number> which i want to increment by 1 for all the XML files.
any help.
i have done the change for a single .txt file, which is okay:-
package ParsingXML;
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.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.NamedNodeMap;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class ReadAndModifyXMLFile {
public static final String xmlFilePath = "C:\\Users\\PSINGH17\\Desktop\\testFile.txt";
public static void main(String argv[]) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(xmlFilePath);
// Get employee by tag name
//use item(0) to get the first node with tag name "employee"
Node employee = document.getElementsByTagName("employee").item(0);
// update employee , increment the number
NamedNodeMap attribute = employee.getAttributes();
Node nodeAttr = attribute.getNamedItem("number");
String str= nodeAttr.getNodeValue();
System.out.println(str);
int val= Integer.parseInt(str);
System.out.println(val);
val=val+1;
System.out.println(val);
String final_value= String.valueOf(val);
System.out.println(final_value);
nodeAttr.setTextContent(final_value);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File(xmlFilePath));
transformer.transform(domSource, streamResult);
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
}
}
xml file:-
<?xml version="1.0" encoding="UTF-8" standalone="no"?><company>
<employee number="14">
<firstname>Pranav</firstname>
<lastname>Singh</lastname>
<email>pranav#example.org</email>
<salary>1000</salary>
</employee>
</company>
So this code uses the initial value digits after hash to start the counter.
Then it iterates through all the files in the folder.
The first file will get the initial value, the rest will get incremented values.
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
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.File;
public class TestFile {
public static final String xmlFileFolder = "C:\\Rahul\\test";
private static final String initialValue = "450-000-1212";
public static void main(String argv[]) {
int baseValue = Integer.parseInt(getValueAfterLastDash(initialValue));
System.out.println("startValue " + baseValue);
File folder = new File(xmlFileFolder);
for (File file : folder.listFiles()) {
try {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(file);
Node employee = document.getElementsByTagName("employee").item(0);
NamedNodeMap attribute = employee.getAttributes();
Node nodeAttr = attribute.getNamedItem("number");
System.out.println(getValueBeforeLastDash(initialValue) + baseValue);
nodeAttr.setTextContent(getValueBeforeLastDash(initialValue) + baseValue);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(file);
transformer.transform(domSource, streamResult);
baseValue++;
} catch (Exception ignored) {
}
}
}
private static String getValueAfterLastDash(String initialValue) {
return initialValue.substring(initialValue.lastIndexOf('-') + 1, initialValue.length());
}
private static String getValueBeforeLastDash(String initialValue) {
return initialValue.substring(0, initialValue.lastIndexOf('-') + 1);
}
}

How to write Multiple Element in the XML using JAVA

Sample XML which i have to generate using JAVA
sense
168
192.168.140.150
002EC0FEFF83EA97
Code Used I have written so far
import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
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 SampleCode {
public static final String xmlFilePath = "C:\\Users\\harsh.sharma\\Desktop\\Sense Performance\\Generated\\xmlfile.xml";
public static void main(String[] args) throws ParseException {
// TODO Auto-generated method stub
try {
String cid_Value="168";
String ip_Value="192.168.140.150";
String id_Value="002EC0FEFF83EA97";
String sensorsid_Value="002EC0FEFF8FFF27";
String desc_Value=" ";
String batt_Value="6.60";
String sig_Value="-55";
String scount_Value="0";
String rdate_Value="15/05/2015 21:47:04";
DateFormat dateFormat = new SimpleDateFormat("dd/MM/YYYY HH:mm:ss");
//get current date time with Date()
#SuppressWarnings("deprecation")
Calendar cal = Calendar.getInstance();
String mdate_Value=dateFormat.format(cal.getTime());
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentFactory.newDocumentBuilder();
Document document = documentBuilder.newDocument();
//root element
Element root = document.createElement("msgs");
document.appendChild(root);
//msg element
Element msg = document.createElement("msg");
root.appendChild(msg);
//type element
Element type = document.createElement("type");
msg.appendChild(type);
type.setTextContent("Sense");
//cid element
Element cid = document.createElement("cid");
msg.appendChild(cid);
cid.setTextContent(cid_Value);
//ip element
Element ip = document.createElement("ip");
msg.appendChild(ip);
ip.setTextContent(ip_Value);
Element errs = document.createElement("errs");
msg.appendChild(errs);
//id element
Element id = document.createElement("id");
msg.appendChild(id);
id.setTextContent(id_Value);
//sensors element
Element sensors = document.createElement("sensors");
msg.appendChild(sensors);
//Sensor element
Element sensor = document.createElement("sensor");
//sensors.appendChild(sensor);
sensor.setAttribute("sensorsid",sensorsid_Value);
sensor.setAttribute("desc",desc_Value);
sensor.setAttribute("batt",batt_Value);
sensor.setAttribute("sig", sig_Value);
sensor.setAttribute("scount",scount_Value);
sensor.setAttribute("rdate",rdate_Value);
sensor.setAttribute("mdate",mdate_Value);
sensors.appendChild(sensor);
// create the xml file
//transform the DOM Object to an XML File
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(document);
StreamResult streamResult = new StreamResult(new File(xmlFilePath));
// If you use
// StreamResult result = new StreamResult(System.out);
// the output will be pushed to the standard output ...
// You can use that for debugging
transformer.transform(domSource, streamResult);
System.out.println("Done creating XML File");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
}
}
}
I want it should give me multiple rows under the sensor Element, I want to write the loop that I can generate multiple data for the sensor Element

Transformer.transform Error: Unable to open 'WfdCommon.jar'

It's my first intention to create XML file for android using TransformerFactory and I have these errors:
W/﹕ Unable to open '/system/framework/WfdCommon.jar': No such file or directory
W/art﹕ Failed to open zip archive '/system/framework/WfdCommon.jar': I/O Error
I'm using this class:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
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;
public class CreateXMLFile {
public static void save(String fName) {
try {
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder =
dbFactory.newDocumentBuilder();
Document document = dBuilder.newDocument();
// adding root element to document
Element rootElement = document.createElement("rootelement");
document.appendChild(rootElement);
// write the content into xml file
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer =
transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
File file = new File(fName);
// Output to file
StreamResult result = new StreamResult(file);
transformer.transform(source, result);
// Output to console for testing:
// StreamResult consoleResult = new StreamResult(System.out);
// transformer.transform(source, consoleResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
I call .save method like this:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
.......
CreateXMLFile.save("test.xml");
}
....
}
Testing to consol works well, but when I'm trying to write the content to a file, it throws Exeption.
I was trying to get information about WfdCommon.jar, but could not find any. I have no idea where to dig. Can anyone help me, please?

Java XML update issue - appendchild() not sucessfully append element

I have an issue when I append a new node to xml dom. The following code is the dom saving code in xmlFactory.java.
import java.io.File;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
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 org.w3c.dom.Document;
import com.ism.msgmgt.domain.Post;
import com.ism.msgmgt.domain.User;
public class XmlFactory {
private static Document userdom;
private static Document postdom;
private static File userfile = new File(User.class.getResource("User.xml").getPath());
static {
try{
DocumentBuilderFactory dbuf = DocumentBuilderFactory.newInstance();
DocumentBuilder dbu = dbuf.newDocumentBuilder();
userdom = dbu.parse(userfile);
DocumentBuilderFactory dbpf = DocumentBuilderFactory.newInstance();
DocumentBuilder dbp = dbpf.newDocumentBuilder();
postdom = dbp.parse(postfile);
} catch (Exception e){
e.printStackTrace();
}
}
public static Document getUserDom(){
return userdom;
}
public static void saveUserDom(){
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
System.out.println(userdom.getFirstChild()+"|"+userdom.getFirstChild().getFirstChild());
DOMSource ds = new DOMSource(userdom);
StreamResult sr = new StreamResult(userfile);
trans.transform(ds, sr);
} catch (Exception e){
throw new RuntimeException(e.getMessage(),e);
}
}
}
Note that the printed output is [users: null]|[#text: ]. Next, it is the code in the UserDao.java.
public class UserDao {
public static Element currentUser = null;
public static Document userdom = XmlFactory.getUserDom();
public static void reg(User u){
clrLogin();
u.setUserid(UidUtil.getUid());
u.setPassword(PwdUtil.encode(u.getPassword()));
Element e = userdom.createElement("user");
e.setAttribute("id", u.getUserid());
e.setAttribute("username", u.getUsername());
e.setAttribute("password", u.getPassword());
e.setAttribute("login", u.getLogin());
userdom.getFirstChild().appendChild(e);
System.out.println(e);
System.out.println(userdom.getFirstChild()+"|"+userdom.getFirstChild().getFirstChild());
XmlFactory.saveUserDom();
currentUser = e;
}
}
Note that in this code, I printed the node I want to add, which is [user: null]. Next, I printed the expecting added node. However, I got the result [users: null]|[#text: ], which is the same as the output printed from above code. So it looks like appendChild() didn't add e to the dom's first node. Please help. Thanks.
XML File
<?xml version="1.0" encoding="UTF-8"?>
<users>
</users>
There's too much context missing from your question, for one, we don't know how the userdom is actually created...
Let me demonstrate, with the following code...
import java.io.ByteArrayOutputStream;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
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.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class Test1 {
public static Document userdom;
public static void main(String[] args) {
try {
userdom = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
Element root = userdom.createElement("users");
Node adoptNode = userdom.adoptNode(root);
userdom.appendChild(adoptNode);
reg();
} catch (ParserConfigurationException | DOMException exp) {
exp.printStackTrace();
}
}
public static void reg() {
Element e = userdom.createElement("user");
e.setAttribute("id", "blah");
e.setAttribute("username", "kermit");
e.setAttribute("password", "bunnies in the air");
e.setAttribute("login", "kermmi");
userdom.getFirstChild().appendChild(e);
System.out.println(e);
System.out.println(userdom.getFirstChild() + "|" + userdom.getFirstChild().getFirstChild());
saveUserDom();
}
public static void saveUserDom() {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
System.out.println(userdom.getFirstChild() + "|" + userdom.getFirstChild().getFirstChild());
DOMSource ds = new DOMSource(userdom);
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
StreamResult sr = new StreamResult(baos);
trans.transform(ds, sr);
System.out.println(new String(baos.toByteArray()));
}
} catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
I get the following output...
[user: null]
[users: null]|[user: null]
[users: null]|[user: null]
<?xml version="1.0" encoding="UTF-8" standalone="no"?><users><user id="blah" login="kermmi" password="bunnies in the air" username="kermit"/></users>
Which clearly demonstrates that the appendChild method is working fine.
An immediate concern is the relationship between...
public static Document userdom = XmlFactory.getUserDom();
and
DOMSource ds = new DOMSource(userdom);
One has to ask, are they the same reference (of userdom)?
Updated
This...
private static File userfile = new File(User.class.getResource("User.xml").getPath());
coupled with this...
StreamResult sr = new StreamResult(userfile);
Are your problems...
First, you are loading an internal resource and you should NEVER wrap these in File entry, internal/embedded resources are not accessible from a File context and need to be loaded in a different way, instead, maitain the URL refernce that getResource results...
private static URL userfile = User.class.getResource("User.xml");
The next line, (StreamResult sr = new StreamResult(userfile);) is trying to write the resulting DOM back to an embedded resource...embedded resources can not be written to in this fashion, hence the reason it would fail in a normal running environment (it might work in your IDE, but that's a different issue).
Basically, you can't maintain this information as an embedded resource, you need to externalise the file onto the disk.
FYI:
If you did use the URL of the resource properly, you would need to change the way you are loading the XML document to something like...
try (InputStream is = userfile.openStream()) {
userdom = dbu.parse(is);
}

I can't edit a node content into an XML file with Java

I'm trying to edit an XML file with Java, the thing is that I need to edit the content & replace them by what I want inside
(I want to replace some nodes that are in Deutsh into French
[for expample <fr>DE1</fr> into <fr>FR1</fr>])
I tried to use :
node.setTextContent(Value);
node.setNodeValue(Value);
But it doesn't work at all
Is there any other function that might work in editing these nodes below ?
Here's the code :
for (int i = memory; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if ((langu.equals(node.getNodeName()))) //langu = "fr"
{
test = node.getTextContent();
if(isCorrect()){}
else if ((manualTr.clickCount >= 0)
){
trash = test;
node.setTextcontent(Value);
// node.setNodeValue("Test");
memory += manualTr.clickCount;
manualTr.clickCount -= 1;
}
}
}
And here's the XML code :
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<titles>
<tome>
<de>DE1</de>
<fr>DE1</fr>
<en>EN1</en>
</tome>
<valhalla>
<de>DE2</de>
<fr>DE2</fr>
<en>EN2</en>
</valhalla>
<vikings>
<de>DE3</de>
<fr>DE3</fr>
<en>EN3</en>
</vikings>
</titles>
Try this.. I am using setTextContent() to update a node value.
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
/**
* #author JayaPrasad
*
*/
public class ParseXml {
public static void main(String[] args) {
System.out.println("Started XML modification");
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document xmlDoc;
xmlDoc = docBuilder.parse(new File("sample.xml"));
NodeList nodes = xmlDoc.getElementsByTagName("fr");
for (int i = 0, length = nodes.getLength(); i < length; i ++) {
((Element)nodes.item(i)).setTextContent("Modified");
}
xmlDoc.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "4");
DOMSource domSource = new DOMSource(xmlDoc);
StreamResult result = new StreamResult(new File("sample.xml"));
transformer.transform(domSource, result);
System.out.println("Modification Done");
} catch (Exception e) {
e.printStackTrace();
}
}
}

Categories