Java 为什么我不能在线程中正确删除带有循环的JDOM节点?
我知道为什么我下面的代码会提出一个问题,xml文件中的一些节点并没有像应该删除的那个样被删除 我需要维护一个java应用程序,这个应用程序的目的是比较两个PDF文件。应用程序从两台服务器提取xml文件中的数据;然后删除两个xml文件中的一些节点以忽略某些部分,最后应用程序将两个处理过的xml文件发送回两个服务器以获取PDF文件,并提取PDF文件以进行字节比较。应用程序使用JDOMAPI来解析和操作xml文件 这是我的密码:Java 为什么我不能在线程中正确删除带有循环的JDOM节点?,java,jdom,Java,Jdom,我知道为什么我下面的代码会提出一个问题,xml文件中的一些节点并没有像应该删除的那个样被删除 我需要维护一个java应用程序,这个应用程序的目的是比较两个PDF文件。应用程序从两台服务器提取xml文件中的数据;然后删除两个xml文件中的一些节点以忽略某些部分,最后应用程序将两个处理过的xml文件发送回两个服务器以获取PDF文件,并提取PDF文件以进行字节比较。应用程序使用JDOMAPI来解析和操作xml文件 这是我的密码: /** * Ignores all Changes of this F
/**
* Ignores all Changes of this Form
*/
@SuppressWarnings("rawtypes")
protected void ignoreChangesSection() {
Element formNumberElement=retrieveElement(getSiapXmlDocument(), FORM_REQUESTED_ELEMENT).getChild(FORM_NUMBER_ELEMENT);
String formNumber=formNumberElement.getText();
/*retrieveElement(getSiapXmlDocument(), DATA_ELEMENT).getChild(APPROACH_RESOURCE_INSTANCE_ELEMENT).
getChild(APPROACH_ELEMENT).removeChildren(CHANGES_ELEMENT);*/
Element approachElement =
retrieveElement(getSiapXmlDocument(), DATA_ELEMENT).getChild(APPROACH_RESOURCE_INSTANCE_ELEMENT).
getChild(APPROACH_ELEMENT);
List changeReasonList1 = approachElement.getChildren(CHANGES_ELEMENT);
if (changeReasonList1!=null)
{
for (int i=0; i<changeReasonList1.size(); i++)
{
Element chngRsn = (Element)changeReasonList1.get(i);
String ind = chngRsn.getChildText(REASON_CHANGE_IND);
if (ind != null && !"".equals(ind))
{
if (ind.equals(CHANGE) || (formNumber.equals("8260-7A") && ind.equals(CHANGE_FORM_7A)))
{
chngRsn.detach();
}
}
}
}
}
/**
*忽略此表单的所有更改
*/
@抑制警告(“原始类型”)
受保护的无效IgnoreChangeSection(){
元素formNumberRelement=retrieveElement(getSiapXmlDocument(),FORM_REQUESTED_元素)。getChild(FORM_NUMBER_元素);
字符串formNumber=formnumberrelation.getText();
/*retrieveElement(getSiapXmlDocument(),数据元素).getChild(方法资源实例元素)。
getChild(接近元素)。removeChildren(更改元素)*/
元素接近元素=
retrieveElement(getSiapXmlDocument(),数据元素).getChild(方法资源实例元素)。
getChild(接近元素);
List changeReasonList1=approachElement.getChildren(CHANGES\u元素);
if(changeReasonList1!=null)
{
对于(int i=0;i),当您分离节点时,也将列表的大小减少一个……考虑一个四个节点的列表,A、B、B、C.</P>
是否要删除/分离B节点
在循环中,您迭代并从0开始,然后移动到1…删除节点1。但是,现在您的列表是:A、B、C,索引是1。然后再次循环,索引是2,指向C,然后退出循环
不删除第二个节点B
这是一个通用的计算错误,在列表中循环时,您无法轻松地从列表中删除节点
Java提供了一个迭代器,JDOM也实现了这个迭代器,这将是您正确的选择…现在,您应该使用JDOM 2.x而不是JDOM 1.x。2会更容易,但是,即使使用JDOM 1…使用迭代器:
for (Iterator it = changeReasonList1.iterator(); it.hasNext();) {
Element chngRsn = (Element)it.next();
if (various reasons) {
// detach the element:
it.remove();
}
}
编辑、更新评论:
两个关键点是:
emt.detach()
approachElement.getChildren(…)
返回一个“活动”列表。对列表的更改反映在元素中,反之亦然
因此,当您在luve列表中循环并将emt
作为索引get(…)
获取时,您将获得一个子元素。当您分离该子元素时,您将断开它与父元素的连接,从而也将该子元素从approachElement
列表中移除。该列表将缩小一
所以,你的循环:
for (int i=0; i<changeReasonList1.size(); i++)
本质上,你也在做:
changeReasonList1.remove(i);
这是关键点……您实际上是在列表循环中执行remove(i)。如果您将JDOM从等式中去掉,则情况更简单:
List<Integer> data = new ArrayList<>();
data.add(1);
data.add(2);
data.add(3);
for (int i = 0; i < data.size(); i++) {
System.out.println("before: " + data.get(i));
if (i == 1) {
data.remove(i);
}
System.out.println("after: " + data.get(i));
}
然后退出
因此,它永远不会“测试”before值3
,因为在删除2
,我们会缩小列表,最后一个循环的大小是2,循环中的索引增加到2,因此循环终止
迭代器避免了这种情况。您好,非常感谢您的帮助!它很有效!我会理解为什么我在以前的代码中分离了错误的节点。我没有使用任何索引作为分离参数;我获取第I个元素并决定是否删除它,如果我应该删除此节点,我使用分离。当我在调试模式下跟踪时,我注意到如果拆离一个节点,列表会缩小,我认为我正在拆离正确的节点,否则控制流无法到达“拆离”。那么为什么会出现此问题?如果您能给我更多提示,我将不胜感激。请编辑以包含更多细节
List<Integer> data = new ArrayList<>();
data.add(1);
data.add(2);
data.add(3);
for (int i = 0; i < data.size(); i++) {
System.out.println("before: " + data.get(i));
if (i == 1) {
data.remove(i);
}
System.out.println("after: " + data.get(i));
}
before: 1
after: 1
before: 2
after: 3