Does anybody have faced the below problem... or have any clue...
In our program we read an XML document from file and parse(DOM Parser) against the DTD. We get the DOM Document object using parser to modify the document, in this case we are adding new element at particular place in the document, we are using XPath to search through the position where new element to be inserted or added to. In the same program in another place it tries to find the new element using XPath expression against the same DOM document that has been modified above by XPath Evaluator API's, it does not find but if you look in the document object the new element is there. I can find the new element by normal DOM API like getElementByTagName() method... More over I can traverse through the new element by executing an XPath expression to an element that is around the new element. Again if I convert the modified DOM document into text
string and parse again through parser to get the new DOM Document object... it works fine with new DOM document object...
following is the sample program...
----------------------------------------------------------------------------------------------------------------------
package
test;
import java.io.FileReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import javax.xml.transform.TransformerException;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xerces.parsers.SAXParser;
import org.apache.xml.utils.PrefixResolver;
import org.apache.xpath.XPath;
import org.apache.xpath.XPathAPI;
import org.apache.xpath.XPathContext;
import org.apache.xpath.objects.XObject;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
* @author nandalrx
*
* To change the template for this generated type comment go to
* Window>Preferences>
Java>Code Generation>Code and Comments
*/
public class ElementAttributeTest
{
/**
* @param xPathString a String containing the Xpath of the element to be
* found
* @returns the corresponding Nodes as and array.
* Returns null if there is no such node
* @throws XPathException
* @throws DOMException
*/
public static XObject getNodesAsList(
PrefixResolver prefixResolver,
XPathContext xPathContext,
XPath xPath,
int ctxtNode)
throws TransformerException, DOMException
{
return xPath.execute(xPathContext, ctxtNode, prefixResolver);
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception
{
DOMParser domParser = new DOMParser();
SAXParser saxParser = new SAXParser();
InputSource is = new InputSource(new FileReader(args[0]));
domParser.parse(is);
/*Get the document to be modified...*/
Document document = domParser.getDocument();
/* get the parent node to be inserted with new child node...*/
Node node = XPathAPI.selectSingleNode(document, args[1]);
/* Create an element to be inserted... */
Element t_n = document.createElement("lndocmeta:smi");
Attr atr = document.createAttribute("lnsmi");
t_n.setAttribute("lnsmi", "ravi");
Node fc = node.getFirstChild();
fc = fc.getNextSibling();
fc = fc.getNextSibling();
/*inserting new element...*/
node.insertBefore(t_n, fc);
/*This is just for self verification of the modified DOM object...*/
String processedString =
convertDOMToString(document, new StringWriter(), "xxx");
// System.out.println(processedString);
/* if I un comment below lines... it works fine... */
// is = new InputSource(new StringReader(processedString));
// domParser.parse(is);
/* This way it finds the element added... */
NodeList list = document.getElementsByTagName("lndocmeta:smi");
//Node smi = XPathAPI.selectSingleNode(document, "/*/lndocmeta
ocinfo/lndocmeta:smi");
for(int i = 0; i < list.getLength(); i++)
{
Node n1 = list.item(i);
System.out.println(n1.getNodeName());
NamedNodeMap nnm = n1.getAttributes();
for(int j = 0; j < nnm.getLength(); j++)
{
Node n2 = nnm.item(j);
System.out.println(n2.getNodeName() + " : " + n2.getNodeValue());
}
}
/* it find the an element that is around an element added... and I can traverse to element added to...*/
Node smi = XPathAPI.selectSingleNode(document, "/*/lndocmeta
ocinfo/lndocmeta:lnlni");
if(smi != null)
{
System.out.println(smi.getNodeName());
smi = smi.getNextSibling();
System.out.println(smi.getNodeName());
}
/* Here it sucks it does not find the new element added in the Modified DOM document object... it returns null... don't know why???
I personally think it is a bug...*/
smi = XPathAPI.selectSingleNode(document, "/*/lndocmeta
ocinfo/lndocmeta:smi");
if(smi != null)
{
System.out.println("++++++ " + smi.getNodeName());
}
}
}
----------------------------------------------------------------------------------------------------------------------
Thanks,