1.11M Members

Inserting a new node using xpath in an xml document

 
0
 

Hi!

i need to insert a new element in an existing xml document. for example,

<details>
<person>
<name>Anu</name>
<email>abc@yahoo.com</email>
</person>
<person>
<name>thara</name>
<email>xyz@gmail.com</email>
</person>
</details>

In this document if i want to insert another element using Xpath, say,<publisher> in <book> node, how to insert it.
I'm using DOM parser for parsing the xml file.
Any help to solve this issue appreciated.


Thanks in advance.

 
0
 

you can try the DocumentBuilderFactory and use :

Element elm = new Element("publishers");
document.createElement(elm);
 
0
 

Thanks for your reply..
But how can i find the exact path to insert the element.
There are two nodes <Person> occur in the xml document. If i want to insert it in the second <person> node then how to find the exact path of it?
I'm trying this for last two days so i'm waiting for your help.
Thanks in advance.

 
0
 

There are two nodes <Person> occur in the xml document. If i want to insert it in the second <person> node then how to find the exact path of it?

Hi here is how you can insert a node "publisher" in the second "person" node. Hope it helps...

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;

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 org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class XMLRW 
{
   public static void main(String[] args)
   {
	   try
	   {
		   BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		   
		   DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	       DocumentBuilder db = dbf.newDocumentBuilder();
	       Document document = db.parse("books.xml");
	       
	       //root 
	       System.out.println(document.getDocumentElement().getNodeName());
	       
	       //no of elemnts
	       NodeList nodeList = document.getElementsByTagName("person");
	       System.out.println(nodeList.getLength());
	       
	       for(int i=0;i<nodeList.getLength();i++)
	       {
	    	   //insert an extra node for the second person
	    	   if(i==1)
	    	   {
	    		   Node node = nodeList.item(i);
	    		   
	    		   Element publisherElm = document.createElement("publisher");
	    		   
	    		   System.out.println("Enter publisher value :");
	    		   String publisher = br.readLine();
	    		   
	    		   publisherElm.appendChild(document.createTextNode(publisher));
	    		   
	    		   node.appendChild(publisherElm);
	    		   
	    		   
	    	   }
	       }
	       
	       TransformerFactory tff  = TransformerFactory.newInstance();
	       Transformer transformer = tff.newTransformer();
	      
	       DOMSource xmlSource = new DOMSource(document);
	       StreamResult outputTarget = new StreamResult("books.xml");
	       
	       transformer.transform(xmlSource, outputTarget);
	       
	       
	       
	   }
	   catch(Exception e)
	   {
		   e.printStackTrace();
	   }
   }
}

and here is your new books.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<details>

	<person>

		<name>Anu</name>

		<email>abc@yahoo.com</email>

	</person>

	<person>

		<name>thara</name>

		<email>xyz@gmail.com</email>

	    <publisher>mcgill pub</publisher>
	</person>

</details>
 
0
 

Thanks for your code.. It works fine..

I'll get get the node name and its value and the position to add the node all in run time only.
I'm displaying the xml in a form display in a jsp page and i have a check box for every node. So when i click a node i'll display the elements that can be added under that corresponding node using the DTD of that xml.
Hereby i'm getting the node name its textvalue and Xpath..
I couln't get the xpath correctly and so i couln't add that element in the proper node.
Here is my code....
It adds the node name and node value but not in the correct location...It adds under the first <person> even if select second <person>

try
        {
         DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
         Document document = documentBuilderFactory.newDocumentBuilder().parse(fname);           
         XPath xpath = XPathFactory.newInstance().newXPath();

    //getting the node name where child node has to be added and adding the node
          
         Node node = (Node) xpath.evaluate(nodepath, document, XPathConstants.NODE);             	
         Node childnode=document.createElement(nodename);        
         node.appendChild(childnode);
         childnode.setTextContent(nodevalue);

       	 Source source = new DOMSource(document);                  
         File file = new File(fname);
         Result result = new StreamResult("books.xml");
         Transformer transformer = TransformerFactory.newInstance().newTransformer();
         transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "books.dtd");
         transformer.transform(source, result);           
         out.close();        	
        }

i'm going wrong in the nodepath..
Can u give me any idea of how to solve this issue?

Thanks in advance.

 
0
 

I dont know XPath very well(thanks to you I started learning it) and I can see you can traverse the node as:

Document document = db.parse("books.xml");

XPathFactory xpathF = XPathFactory.newInstance();
XPath xpath = xpathF.newXPath();
XPathExpression expr = xpath.compile("/details/person[2]/publisher/text()");
 
0
 
/details/person[2]/publisher/text()

Yes you are correct but i dont know to get the Xpath with the index (Person[2]).
i manipulate only with

/details/person/publisher/text()

Still now i proceeded the xpath without the index as i couldn't get the index. I tried in my code where i parsed the document to find the xpath and didnt find the solution since i want my code to be generic for all xml files.Do you have any idea of how to find the xpath with its index.
Your help is expected.

Thanks,
Indu

 
0
 

Do you have any idea of how to find the xpath with its index.

I am not sure that I get what you try to mean, but you might be able to do it by:

NodeList nodeList = document.getElementsByTagName("person");
for(int i=0;i<nodeList.getLength();i++)
{
 if(i==1)
{
  //put your code here using i
}
}

I am not very sure, but I hope this helps...

 
0
 

Thanks..
your code works perfect if i know the position of insertion before itself.
But in my project the user may select any position that is they may choose any <person> node for inserting the child nodes. So finding the xpath with index position may provide a solution.

What i'm trying to do is an xml editor that allows editing of any xml file.
Can you get me my idea now?

 
0
 

But in my project the user may select any position that is they may choose any <person> node for inserting the child nodes.

Ok so now I get it..you want the index to be user-chosen. Now if the list of users is a drop-down,I think you can use a scripting language like jquery to hold the value chosen and pass it as a variable in your xpath. Sounds far-fetched,but you can give it a try...

 
0
 

U got it correctly..
The user will choose the node by clicking a check box under which they have to insert the child node. Then i'll read the DTD and display the user that what are the child nodes that are allowed to add under that node. After that i'll pass the xpath of the parent node and the chilld node to a servlet where i'll perform the node insertion into the correponding xml doument.
If i fetch the xpath along with its index then i can insert it correctly.
I'm working on it.
I'll post once the issue get resolved.

Thanks for your reply.

 
0
 

Thanks ...I d like to see your issue resolved too...

You
This article has been dead for over six months: Start a new discussion instead
Post:
Start New Discussion
Tags Related to this Article