开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜