今天操作XML的时候,用到了批量循环子节点后删除不满足条件的节点..出现了问题..搞了一个多小时..才发现这个问题的所在.. 先来看看正常的程序是如何实现的/
1for(int i = 0 ; i < xndList.Count; i ++ ) //遍历节点2 {3 XmlElement xn = (XmlElement)xndList[i];4 XmlNode x_ID = xn.SelectSingleNode("ID");5 if (x_ID.InnerText != ID) //删除满足条件的子节点6 {7 root.RemoveChild(xn);8 }9 }
大眼看去,是正确的,也是合理..但是效果确不对..测试后发现只能删除一部分的节点..于是断点再断点,观察再观察..终于发现问题所在..就是循环中的这个i的值有问题...因为每次循环,删除节点后,xndList.Count的值都会-1,例如:我当前的Count是5,i=1,第一次循环Count(5)-1=4,则这个时候的i++就是2,第二次的时候Count(4)-1就是3,而i++后就是3,所以满足条件i<Count,于是退出循环..这样就造成了没有完全遍历XML文件的全部节点而造成结果和我们预期的不一样.当然你用foreach(XmlNode in XndList.Count)的办法也不行...我最后的解决办法就是:先确定节点总数,然后循环Count=节点总数,然后在删除节点后,重新获取节点总数,在判断节点总数是否为0,如果为0则退出循环..这样做就可以保证循环能完全遍历全部字节点,并且删除满足条件的所有子节点..具体的代码如下..
1for(int i = 0 ; i < xndList.Count; i ++ ) //遍历节点2 {3 XmlElement xn = (XmlElement)xndList[i];4 XmlNode x_ID = xn.SelectSingleNode("ID");5 if (x_ID.InnerText != ID) //删除满足条件的子节点6 {7 root.RemoveChild(xn);8 }9 }
大眼看去,是正确的,也是合理..但是效果确不对..测试后发现只能删除一部分的节点..于是断点再断点,观察再观察..终于发现问题所在..就是循环中的这个i的值有问题...因为每次循环,删除节点后,xndList.Count的值都会-1,例如:我当前的Count是5,i=1,第一次循环Count(5)-1=4,则这个时候的i++就是2,第二次的时候Count(4)-1就是3,而i++后就是3,所以满足条件i<Count,于是退出循环..这样就造成了没有完全遍历XML文件的全部节点而造成结果和我们预期的不一样.当然你用foreach(XmlNode in XndList.Count)的办法也不行...我最后的解决办法就是:先确定节点总数,然后循环Count=节点总数,然后在删除节点后,重新获取节点总数,在判断节点总数是否为0,如果为0则退出循环..这样做就可以保证循环能完全遍历全部字节点,并且删除满足条件的所有子节点..具体的代码如下..
1for(int i = 0 ; i < xndList.Count; i ++ ) //遍历节点2 {3 XmlElement xn = (XmlElement)xndList[i];4 XmlNode x_ID = xn.SelectSingleNode("ID");5 if (x_ID.InnerText != ID) //删除满足条件的子节点6 {7 root.RemoveChild(xn);8 }9 }
大眼看去,是正确的,也是合理..但是效果确不对..测试后发现只能删除一部分的节点..于是断点再断点,观察再观察..终于发现问题所在..就是循环中的这个i的值有问题...因为每次循环,删除节点后,xndList.Count的值都会-1,例如:我当前的Count是5,i=1,第一次循环Count(5)-1=4,则这个时候的i++就是2,第二次的时候Count(4)-1就是3,而i++后就是3,所以满足条件i<Count,于是退出循环..这样就造成了没有完全遍历XML文件的全部节点而造成结果和我们预期的不一样.当然你用foreach(XmlNode in XndList.Count)的办法也不行...我最后的解决办法就是:先确定节点总数,然后循环Count=节点总数,然后在删除节点后,重新获取节点总数,在判断节点总数是否为0,如果为0则退出循环..这样做就可以保证循环能完全遍历全部字节点,并且删除满足条件的所有子节点..具体的代码如下..
1int len = xndList.Count; //定义节点总数 2 for(int i = 0 ; i < len; i ++) //循环节点总数,保证能遍历节点 3 { 4 XmlElement xn = (XmlElement)xndList[0]; 5 XmlNode x_ID = xn.SelectSingleNode("ID"); 6 if (x_ID.InnerText != FriendID) 7 { 8 root.RemoveChild(xn); 9 10 }11 int xx = xndList.Count; //在这里再次获取节点总数,防止节点泄漏12 if (xx == 0) { //如果没有子节点则退出13 break;14 }15 }其实这个问题和以前第一次写for循环的情况很类.我记得第一次写循环的时候是这样:..希望碰到类似问题的朋友要注意哦..for (int i = 0 ;i < 10;i ++){ //本意是输出1-10的 Response.Write(i); i++; //结果忽略了这里的变化.} 另外的方案:1for(int i = xndList.Count-1 ; i >=0; i --) //遍历节点 2 { 3 XmlElement xn = (XmlElement)xndList[i]; 4 XmlNode x_ID = xn.SelectSingleNode("ID"); 5 if (x_ID.InnerText != ID) //删除满足条件的子节点 6 { 7 root.RemoveChild(xn); 8 } 9 }