Adding data to XML DOM tree

E

el_bandido

Hello,

I'm having the hardest time do the simplest things in Java. Consider
following XML document:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE KNOWHOWDB SYSTEM "null">
<KNOWHOWDB xmlns="http://www.why-is-it-so-hard.com/">
<DOCUMENT path="../aaa/bbb.ext">
<KEYWORDS>
<KEYWORD>Hello</KEYWORD>
<KEYWORD>World</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../aaa/ccc.ext">
<KEYWORDS>
<KEYWORD>Some</KEYWORD>
<KEYWORD>gap</KEYWORD>
<KEYWORD>filler</KEYWORD>
</KEYWORDS>
</DOCUMENT>
</KNOWHOWDB>

I'm writing a Servlet that should add a new DOCUMENT and its appropriate
KEYWORDs. How can I do this? Does anyone have any good pointers? I've
been searching the net for hours now, I only get examples of replacing
an entry or creating a new XML document from scratch, but I want to add
some elements to my XML tree.

Let's say my HTML input form provided me with follwing information:

path="../bbb/aaa.ext"
keywords="some text meant as keywords"

The resulting XML tree/file would look like:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE KNOWHOWDB SYSTEM "null">
<KNOWHOWDB xmlns="http://www.why-is-it-so-hard.com/">
<DOCUMENT path="../aaa/bbb.ext">
<KEYWORDS>
<KEYWORD>Hello</KEYWORD>
<KEYWORD>World</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../aaa/ccc.ext">
<KEYWORDS>
<KEYWORD>Some</KEYWORD>
<KEYWORD>gap</KEYWORD>
<KEYWORD>filler</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../bbb/aaa.ext">
<KEYWORDS>
<KEYWORD>some</KEYWORD>
<KEYWORD>text</KEYWORD>
<KEYWORD>meant</KEYWORD>
<KEYWORD>as</KEYWORD>
<KEYWORD>keywords</KEYWORD>
</KEYWORDS>
</KNOWHOWDB>


My efforts so far (extremely simplified code):
----------------------------------------------
private void knowhow_add_XML() throws Exception {
DOMParser parser = new DOMParser();
parser.parse(XMLFILE);
Document doc = parser.getDocument();

Element root = doc.getDocumentElement();
NodeList descriptionElements = root.getElementsByTagName("KEYWORDS");
Element descriptionElement = (Element) descriptionElements.item(0);

Text descriptionText;
Iterator it = keywords.iterator();
while (it.hasNext()) {
descriptionElement = doc.createElement("KEYWORD");
descriptionText = doc.createTextNode(it.next().toString());
descriptionElement.appendChild(descriptionText);
root.appendChild(descriptionElement);
}

File file = new File(XMLNEW);
Writer writer = new FileWriter(file);
serializeNodeXML(doc, writer, "");
writer.flush();
writer.close();
}

The serializeNodeXML() method will write out the XML file. However I
seem to be completely unable to add any DOCUMENTS or KEYWORDs at an
intelligent place in the tree nor will the outcoming tree be correct.
I've skimmed through the SUN XML parsing documentation, through the
"Java & XML" book and "Java in a Nutshell" but I couldn't find the
answer to my simple problem. I don't want to add the append code into
the serializer as this would defeat the purpose of merging XML trees in
Java programming wise. [A beginners documentation on DOM parsing and
modifying and adding would be excellent.]

Thanks for any pointers,
Roberto Nibali, ratz
 
E

el_bandido

My efforts so far (extremely simplified code):
----------------------------------------------
private void knowhow_add_XML() throws Exception {
DOMParser parser = new DOMParser();
parser.parse(XMLFILE);
Document doc = parser.getDocument();

Element root = doc.getDocumentElement();
NodeList descriptionElements = root.getElementsByTagName("KEYWORDS");
Element descriptionElement = (Element) descriptionElements.item(0);

Text descriptionText;
Iterator it = keywords.iterator();
while (it.hasNext()) {
descriptionElement = doc.createElement("KEYWORD");
descriptionText = doc.createTextNode(it.next().toString());
descriptionElement.appendChild(descriptionText);
root.appendChild(descriptionElement);
}

File file = new File(XMLNEW);
Writer writer = new FileWriter(file);
serializeNodeXML(doc, writer, "");
writer.flush();
writer.close();
}

Now it sort of works, except that the output is not nice:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE KNOWHOWDB SYSTEM "null">
<KNOWHOWDB xmlns="http://www.why-is-it-so-hard.com/">
<DOCUMENT path="../aaa/bbb.ext">
<KEYWORDS>
<KEYWORD>Hello</KEYWORD>
<KEYWORD>World</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../aaa/ccc.ext">
<KEYWORDS>
<KEYWORD>Some</KEYWORD>
<KEYWORD>gap</KEYWORD>
<KEYWORD>filler</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../bbb/aaa.ext">
<KEYWORDS>
<KEYWORD>some</KEYWORD><KEYWORD>text</KEYWORD><KEYWORD>meant</KEYWORD><KEYWORD>as</KEYWORD><KEYWORD>keywords</KEYWORD>
</KEYWORDS> </KNOWHOWDB>

The code now reads as follows:

private void knowhow_add_XML() throws Exception {
DOMParser parser = new DOMParser();
parser.parse(XMLFILE);
Document doc = parser.getDocument();
Element root = doc.getDocumentElement();

NodeList descElements = root.getElementsByTagName("DOCUMENT");
Element myDoc = (Element) descElements.item(0);
myDoc = doc.createElement("DOCUMENT");
Attr myAttr = doc.createAttribute("path");
Text myAttrText = doc.createTextNode(uploadfile);
myAttr.appendChild(myAttrText);
myDoc.setAttributeNode(myAttr);
Element myKeywords = doc.createElement("KEYWORDS");

Element myKeyword;
Text myKeyText;

Iterator myIt = keywords.iterator();
while (myIt.hasNext()) {
myKeyword = doc.createElement("KEYWORD");
myKeyText = doc.createTextNode(myIt.next().toString());
myKeyword.appendChild(myKeyText);
myKeywords.appendChild(myKeyword);
}

myDoc.appendChild(myKeywords);
root.appendChild(myDoc);

File file = new File(XMLNEW);
Writer writer = new FileWriter(file);
serializeNodeXML(doc, writer, "");
writer.flush();
writer.close();
}

Remaining questions now are:

1. What can I do to have the XML output nicely indented? .normalize()
doesn't cut it.
2. Is the writer.flush(); writer.close() necessary or maybe even good
Java coder's practice?
3. When I reload the servlet (served by tomcat) my class variables are
not overwritten. I've read that even when running SingleThreadModel
that class or static variables are not thread safe. Is this true?
4. I have a HTML input form which calls my servlet and as a reply I
would like to output a mix between static webpage and dynamic. To
be more to the point, I have a search.html which is developed by a
third party and I need to output this search.html in the response
_but_ including some dynamic content from the search function. My
idea was to have the third party guys generate the html with kind of
a comment marker inside. I could then read the file line by line
and put it into a StringBuffer until I get to the marker, add the
dynamic output and continue with the reading. Like so asynchronous
and independent development of the "coporate design" is possible. Is
there a better way to achieve this?

Thanks and best regards,
Roberto Nibali, ratz
 
J

John C. Bollinger

Hello,

I'm having the hardest time do the simplest things in Java. Consider
following XML document:

XML is not simple.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE KNOWHOWDB SYSTEM "null">
<KNOWHOWDB xmlns="http://www.why-is-it-so-hard.com/">
<DOCUMENT path="../aaa/bbb.ext">
<KEYWORDS>
<KEYWORD>Hello</KEYWORD>
<KEYWORD>World</KEYWORD>
</KEYWORDS>
</DOCUMENT>
<DOCUMENT path="../aaa/ccc.ext">
<KEYWORDS>
<KEYWORD>Some</KEYWORD>
<KEYWORD>gap</KEYWORD>
<KEYWORD>filler</KEYWORD>
</KEYWORDS>
</DOCUMENT>
</KNOWHOWDB>

I'm writing a Servlet that should add a new DOCUMENT and its appropriate
KEYWORDs. How can I do this? Does anyone have any good pointers? I've
been searching the net for hours now, I only get examples of replacing
an entry or creating a new XML document from scratch, but I want to add
some elements to my XML tree.

DOM in particular is not simple, and is also not Java-specific.

To add a Node of any type to a DOM Document, you first create the Node
by the appropriate createXXX() method of the Document object. Then, on
the intended parent of the new Node, you invoke either the
appendNode(Node) method or the insertBefore(Node, Node) method. That's
all there is to it. You may also want to configure the new Node to your
liking, but that's not a necessary part of actually adding it to the tree.
My efforts so far (extremely simplified code):
----------------------------------------------
private void knowhow_add_XML() throws Exception {
DOMParser parser = new DOMParser();
parser.parse(XMLFILE);
Document doc = parser.getDocument();

Element root = doc.getDocumentElement();

So far, so good.
NodeList descriptionElements = root.getElementsByTagName("KEYWORDS");
Element descriptionElement = (Element) descriptionElements.item(0);

But here you lose me. It looks like you don't actually use these
objects, so why do you create them?
Text descriptionText;
Iterator it = keywords.iterator();

Where did variable "keywords" come from? I take it it's a List of
Strings containing the desired keyword text?
while (it.hasNext()) {
descriptionElement = doc.createElement("KEYWORD");
descriptionText = doc.createTextNode(it.next().toString());
descriptionElement.appendChild(descriptionText);

The above part of this loop looks fine on first glance,
root.appendChild(descriptionElement);

but what's up with that? You are trying to append elements to the
document element, which (per XML) should have only one element child,
the root element. In your case, the root element is named "KNOWHOWDB".
You need to create and configure an element to hold the keywords
(which in your case would be named DOCUMENT), and append it as a child
of the root element. The root element is not the same thing as the
Document node. You should then create the keyword elements, which you
seem to already know how to do, and then append them to the "DOCUMENT"
element you just created.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top