Reputation: 1689
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>
Upvotes: 0
Views: 1342
Reputation: 347214
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);
}
Upvotes: 1