我正在使用以下代码从XMl文件中删除多个元素。
NodeList removeNodeList = doc.getElementsByTagName("server1");
Element rootElement = doc.getDocumentElement();
for (int i = 0; i < removeNodeList.getLength(); i++) {
rootElement.removeChild(removeNodeList.item(i));
}
但是在删除一个元素之后它就会脱离循环。问题是什么。
以下是我的XML文件内容。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<start>
<category name="server1"/>
<category name="server2"/>
<server1 name="serverName1" value="serverValue"/>
<server1 name="serverName1" value="serverValue"/>
<server2 name="serverName2" value="serverValue"/>
</start>
答案 0 :(得分:1)
我找到了解决方案:
让我详细解释一下这个问题。
NodeList removeNodeList = doc.getElementsByTagName("server1");
removeNodeList.getLength()
将返回2,因为有2个节点具有nodeName server1
,然后执行rootElement.removeChild(removeNodeList.item(i));
,然后检查for loop
条件i.e.
i
的值是1
而removeNodeList.getLength()
返回1
,因为现在server1
中仅有1个nodeName为DOM document
的节点,此条件失败为1 < 1 is false
< / p>
所以我采用了以下方法:
一旦不再使用NodeList,就删除所有元素。
NodeList nodes = doc.getElementsByTagName(elementName);
Set<Element> targetElements = new HashSet<Element>();
for (int i = 0; i < nodes.getLength(); i++) {
Element e = (Element)nodes.item(i);
targetElements.add(e);
}
for (Element e: targetElements) {
e.getParentNode().removeChild(e);
}
答案 1 :(得分:0)
从列表中删除元素会将其大小减1,这会破坏迭代。您需要按照此问题中的描述向后迭代列表(从最后一个节点到第一个节点):
答案 2 :(得分:0)
如前所述,删除元素会减小列表的大小,但计数器仍在增加(i ++):
var request = new Request(cacheKey, {credentials: 'include'});
return fetch(request).then(function(response) {
我认为最简单的解决方案是在循环中删除i ++部分。
[element 1] <- Delete
[element 2]
[element 3]
[element 4]
[element 5]
[element 2]
[element 3] <- Delete
[element 4]
[element 5]
--
[element 2]
[element 4]
[element 5] <- Delete
--
--
[element 2]
[element 4]
--
--
--
指针停留在同一位置。 列表会自行移动。
for (int i = 0; i < removeNodeList.getLength();) {
rootElement.removeChild(removeNodeList.item(i));
}
答案 3 :(得分:0)
由于该节点也已从removeNodeList
中删除,因此下一个要删除的节点位于removeNodeList
中的索引0上,直到列表为空(removeNodeList.getLength() == 0
)
while(removeNodeList.getLength() > 0) {
rootElement.removeChild(removeNodeList.item(0));
}
仅当每个节点"server1"
是节点"start"
的子节点时,此方法才有效。
如果xml将包含"server1"
个节点作为不同于节点rootElement
的节点的子节点(“启动”),则将抛出DOMException,因为要删除的节点不是rootElement
的子节点。
例如:
<category name="server1"/>
<category name="server2"/>
<server1 name="serverName1" value="serverValue"/>
<other>
<server1 name="serverName1" value="serverValue"/>
</other>
<server2 name="serverName2" value="serverValue"/>
要处理这种情况,请删除该项目的父节点:
while(removeNodeList.getLength() > 0) {
Node itemToRemove = removeNodeList.item(0);
itemToRemove.getParentNode().removeChild(itemToRemove);
}
仅当方法shouldRemoveNode()
返回true时,才会删除节点。
如果为false,则该节点保留在文档和removeNodeList
中,(可能)要删除的下一个节点位于索引=当前索引+ 1
notRemovedCnt
既是未删除的节点数,也是下一个要检查是否应删除的元素的索引,
只要removeNodeList
的长度和notRemoveCnt
相等,就意味着列表中没有要删除的元素。
int notRemovedCnt = 0;
while(removeNodeList.getLength() > notRemovedCnt) {
Node itemToRemove = removeNodeList.item(notRemovedCnt);
if (shouldRemoveNode(itemToRemove)) {
itemToRemove.getParentNode().removeChild(itemToRemove);
} else {
notRemovedCnt++;
}
}