tags:

views:

465

answers:

3

I have seen the same question being answered for vb and c#, but i need a Java best solution for appending nodes to an xml. Will xpath help? I have

<A>
  <B>
    <c>1<c/>
    <d>2<d/>
    <e>3<e/>
  </B>
  <B>
    <c>1<c/>
    <d>2<d/>
    <e>3<e/>
  </B>
</A>

Need to append another

<B>
   <c>11<c/>
   <d>21<d/>
   <e>31<e/>
</B>
+1  A: 

XPath will help you to find nodes, but not really append them. I don't think you'd find it particularly useful here.

Which XML API are you using? If it's the W3C DOM (urgh) then you'd do something like:

Element newB = document.createElement("B");
Element newC = document.createElement("c");
newC.setTextContent("11");
Element newD = document.createElement("d");
newD.setTextContent("21");
Element newE = document.createElement("e");
newE.setTextContent("31");
newB.appendChild(newC);
newB.appendChild(newD);
newB.appendChild(newE);
document.getDocumentElement().appendChild(newB);
Jon Skeet
and setting c , d, e values?
Ajay
Editing... although if you wanted to see how to create content within those elements, it would have been useful to say so in the question.
Jon Skeet
sorry... have done that!.. thanks for the reply
Ajay
+1  A: 

The most strait-forward way is that you parse, using Sax or Dom, all the files into a data structure, for example an A class which has a B class with members of C,D,E class in your case.

And output the data structure back to XML.

Winston Chen
A: 

You may want to use XMLModier of vtd-xml to do it in a cool way, which is to append the byte content directly... You just need to call XMLModier's insertAfterElement()... below is a link to the code sample: Incrementally Modify XML in Java:

import com.ximpleware.*;
import java.io.*;

public class ModifyXML {
     public static void main(String[] s) throws Exception{
        VTDGen vg = new VTDGen(); // Instantiate VTDGen
        XMLModifier xm = new XMLModifier(); //Instantiate XMLModifier
        if (vg.parseFile("old.xml",false)){
             VTDNav vn = vg.getNav();
             xm.bind(vn);

             // first update the value of attr
             int i = vn.getAttrVal("attr");
             if (i!=-1){
                  xm.updateToken(i,"value");
             }

             // navigate to <a>
            if (vn.toElement(VTDNav.FC,"a")) {
                  // update the text content of <a>
                   i=vn.getText();
                   if (i!=-1){
                      xm.updateToken(i," new content ");
                   }
                   // insert an element before <a> (which is the cursor element)
                   xm.insertBeforeElement("<b/>\n\t");

                   // insert an element after <a> (which is the cursor element)
                   xm.insertAfterElement("\n\t<c/>");
            }

            xm.output(new FileOutputStream("new.xml"));
         }
     }

}
vtd-xml-author
Would you mind adding why this is a cool way? It sounds the opposite of anything I've ever heard of. Also, why is this answer Community Wiki?
John Saunders
it is cool because it is directly byte level append, as opposed to data strcuture level append... I think I explained that in my post... "append byte content"
vtd-xml-author
Yes, you just didn't say why byte level append is cool, and not simply a bad idea that makes the code dependent on the encoding of the XML document.
John Saunders
And you didn't answer why you feel this answer should be CW when the question is not, and none of the other answers are. Please see http://meta.stackoverflow.com/questions/7931/how-does-stackoverflow-work-the-official-faq about CW.
John Saunders