0

我正在使用 org.w3c.dom.Document 进行 xml 解析。我的服务器中有一个 xml 文件,例如..

<query><item access='server1'><item access='server2'><item access='server3'></query>

我将读取此 xml 文件并根据某些选项,我将动态删除任何节点(server1 或 server2 或 server3)并将结果作为字符串返回,以便我可以在我的一个用户界面中显示。下面是代码

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)
{
}

现在,问题是---> 有时节点没有被删除。例如,如果我删除了 server1 属性节点——它被删除了。然后我再次尝试删除 server2 属性节点。它显示不应该的 server1 节点。如果我使用了正确的删除节点的方法,请告诉我。

谢谢

4

2 回答 2

1

我刚刚意识到,在 for 循环中,一旦我删除节点,xml 节点的总大小就会减少 1,并且 xml 结构会重新排列......所以它将进一步推进 1 个节点。我将代码更改为

for(int i =0 ; i < nList.getLength();)
{
   //operation/

  //remove case match
   {
     //remove
     i=0;
     contiune;
   }
  i++
}

这对我有用!!!

于 2013-03-14T16:41:09.093 回答
1

当您删除节点列表中的节点时,DOM 会重新排列它,您的索引将是错误的。

DOM 中的 NodeList 和 NamedNodeMap 对象是活动的;也就是说,对底层文档结构的更改会反映在所有相关的 NodeList 和 NamedNodeMap 对象中。

孩子的解决方案有效,但可能无效。所以我只是稍微编辑一下。

int j = 0;
for(int i =0 ; i < nList.getLength();)
{
   //operation/

  //remove case match
   {
     //remove
     i=j;
     continue;
   } else {
     j++;
   }
  i++
}

我确实尝试过,它对我有用。

于 2014-03-27T17:52:18.540 回答