My recursive function is not working properly
have an xml file like this.
<?xml version ="1.0" encoding ="utf-8"?>
<menu>
<menuNode title="Register" value="true">
<menuNode title="Company" value="false">
<menuNode title="Add" value="false" />
<menuNode title="Modify" value="false" />
<menuNode title="Delete" value="false" />
</menuNode>
<menuNode title="SubCategory" value="true">
<menuNode title="Add" value="false" />
<menuNode title="Modify" value="false" />
<menuNode title="Delete" value="false" />
&开发者_运维百科lt;/menuNode>
<menuNode>
</menu>
I want to remove all nodes with value=false I wrote a recursive function like this , but its not working prooperly.
Public Sub RemoveValueFalseNodes(ByVal MyMenuSource As XElement)
For Each myMenuNode In MyMenuSource.Elements
If myMenuNode.Elements.Count > 0 Then
RemoveValueFalseNodes(myMenuNode)
End If
If myMenuNode.Attribute("value").Value = "false" Then
myMenuNode.Remove()
End If
Next
End Sub
You should never modify a collection while you're enumerating it. Typically it will throw an exception when you try but sometimes it just screws up the results. Instead you should consider doing something like the following (sorry for the c# but I don't really know VB.NET LINQ)
var nodes = from x in MyMenuSource.Descendants("menuNode")
where !(bool)x.Attribute("value")
select x;
foreach (var node in nodes.ToArray()) {
node.Remove();
}
The two things to note about the above - I'm using the Descendants() method to avoid having to do a recursive dive of the XML tree. Also I'm turning the collection into an array which takes a "snapshot" of the results so that removing an element does not disturb the XML structure while the query is still active.
Never remove an element of an array while iterating over it, or take proper actions. In this case, you should simply iterate over MyMenuSource.Elements
from back to front, so deleting an element doesn't cause trouble in your next iteration.
精彩评论