Reputation: 1626
I'am using org.w3c.dom.Document for xml parsing.I have a xml file in my server like..
<query><item access='server1'><item access='server2'><item access='server3'></query>
I will read this xml file and based on some option's i will remove any of the node(server1 or server2 or server3) dynamically and return the result as a string so that i can show in one of my user interface.below is the code
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setIgnoringComments(true);
inputStream = new FileInputStream(new File(filename));
org.w3c.dom.Document doc = documentBuilderFactory.newDocumentBuilder().parse(inputStream);
Element rootNode = doc.getDocumentElement();
if(filename.endsWith("items.xml"))//load the enabled items
{
NodeList nList = doc.getElementsByTagName("item");
for(int i = 0; i < nList.getLength(); i++)
{
try
{
Node node = nList.item(i);
if((node.getNodeType() == Node.ELEMENT_NODE))
{
Element ele = (Element)node;
String access = (String)ele.getAttribute("access");
String level = access.substring(0,access.indexOf("."));
if(!LevelManager.isLevelEnabled(level))
{
rootNode.removeChild(node);
}
}
else
{
System.out.println("NO ELEMENT NODE");
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
doc.normalize();
StringWriter stw = new StringWriter();
Transformer serializer = TransformerFactory.newInstance().newTransformer();
serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
serializer.transform(new DOMSource(doc), new StreamResult(stw));
discfeatures = stw.toString();
return discfeatures;
}
catch(Exception w)
{
}
Now, the issue is ---> sometimes nodes are not removing.Say for example if I remove server1 attribute node -- its removed. and then I again try to remove server2 attribute node.it shows server1 node which should'nt.Please let me know if I am using the proper way of removing the node.
Thanks
Upvotes: 0
Views: 5233
Reputation: 41
When you remove a node in node list, the DOM rearrange it and your index will be wrong.
NodeList and NamedNodeMap objects in the DOM are live; that is, changes to the underlying document structure are reflected in all relevant NodeList and NamedNodeMap objects.
The kiddo's solution worked but it may be ineffective. So I just edit it a little bit.
int j = 0;
for(int i =0 ; i < nList.getLength();)
{
//operation/
//remove case match
{
//remove
i=j;
continue;
} else {
j++;
}
i++
}
I did try it and it worked for me.
Upvotes: 1
Reputation: 1626
I just realized that in the for loop, once I remove the node the total size of the xml node decrease by 1 and xml structure re-arrange's..so it will advance 1 node futher. I changed my code as
for(int i =0 ; i < nList.getLength();)
{
//operation/
//remove case match
{
//remove
i=0;
contiune;
}
i++
}
This worked for me!!!
Upvotes: 1