java - RemoveChild 删除第一个同名的孩子,但跳过下一个同名的孩子
问题描述
我有这个节点
<Record status="updated">
<ID_Country>5</ID_Country>
<ID_Currency>162</ID_Currency>
<IsoCodeNumber>16 </IsoCodeNumber>
<IsoCodeLetter version="old">AS </IsoCodeLetter>
<IsoCodeLetter version="new">ASAS </IsoCodeLetter>
<PostCode> </PostCode>
<CountryName>American Samoa </CountryName>
<isEuCountry>0</isEuCountry>
</Record>
我正在尝试将此节点添加到另一个 XML 文件中并看起来像这样。
<Record>
<ID_Country>5</ID_Country>
<ID_Currency>162</ID_Currency>
<IsoCodeNumber>16 </IsoCodeNumber>
<IsoCodeLetter>ASAS </IsoCodeLetter>
<PostCode> </PostCode>
<CountryName>American Samoa </CountryName>
<isEuCountry>0</isEuCountry>
</Record>
这是我使用的代码
Node updatedNode = diffNode.cloneNode(true);
((Element) updatedNode).removeAttribute("status");
for (int i = 0; i < updatedNode.getChildNodes().getLength(); i++)
{
if (updatedNode.getChildNodes().item(i).getNodeType() == Node.ELEMENT_NODE)
{
Element e = (Element)updatedNode.getChildNodes().item(i);
String string = e.getNodeName();
if (e.hasAttribute("version") && e.getAttribute("version").equals("old"))
{
((Element) updatedNode).removeChild((Node)e);
}
if(e.hasAttribute("version") && e.getAttribute("version").equals("new"))
{
e.removeAttribute("version");
}
}
}
productXML.adoptNode(updatedNode);
prodRoot.insertBefore(updatedNode, nextNode);
由于某种原因,当循环通过第一个 IsoCodeLetter 节点并将其删除时,它会跳过下一个并转到 PostCode,但第二个 IsoCodeLetter 仍在新节点中,我将其附加到 XML 文件中,看起来像这样。
<Record>
<ID_Country>5</ID_Country>
<ID_Currency>162</ID_Currency>
<IsoCodeNumber>16 </IsoCodeNumber>
<IsoCodeLetter version="new">ASAS </IsoCodeLetter>
<PostCode> </PostCode>
<CountryName>American Samoa </CountryName>
<isEuCountry>0</isEuCountry>
</Record>
你有什么想法为什么会发生这种情况以及如何解决它?我正在使用 DOMParser 编写 XML 文件。
解决方案
通过从元素中删除一个子元素,您将它从子节点中删除,这意味着下一个子元素现在位于您删除的子元素的索引处。但是你的循环继续下一个索引,跳过那个孩子。例如:假设您有:
0:孩子 A 1:孩子 B 2:孩子 C 3:儿童 D
对于i == 0
,假设您不删除 Child A。您的循环将 1 添加到i
,然后继续i == 1
。您确实删除了 Child B。现在您有:
0:孩子 A 1:儿童 C 2:儿童 D
..但是您的循环i
现在添加了一个,而i == 2
您看到的下一个孩子是孩子 D。您从未看过孩子 C。
通常的解决方案是:
向后循环,因此索引正在减少,因此是否删除给定索引处的子级无关紧要;或者
在修改元素之前拍摄子节点列表的快照,这样当您从元素中删除子节点时,它不会从快照中删除
倒退是一个很容易的改变:
for (int i = updatedNode.getChildNodes().getLength() - 1; i >= 0; i--)
旁注:我可能也getChildNodes
只调用一次并重用生成的NodeList
对象:
NodeList children = updatedNode.getChildNodes();
for (int i = children.getLength() - 1; i >= 0; i--)
// ...and use `children`, not `updatedNode.getChildNodes()`, in the loop body...
}
推荐阅读
- tabulator - 如何获取 Tabulator 表中所有列的宽度?
- python - Open XML 文档保护实现(documentProtection 类)
- python - 如何使用 numpy 对带有条件的掩码加权平均值进行矢量化?
- django - django:如何实现 public like 按钮
- gitlab - 如何使用管道在 Hashicorp Vault 中编写角色和策略
- django - 从中间表名获取 M2M 模型
- python - 如何将 IPv4 和 IPv6 源地址绑定到 Python 套接字?
- c# - 试图在 C# 中实现一个双跳函数,在 Godot 游戏引擎中限制为 2 次跳转
- python - Tensorflow Object Detection API 配置文件中“keep_aspect_ratio_resizer {”的作用是什么?
- database - 在数据库分片的情况下如何处理故障转移?