I have an XML document as follows:
<Menu>
<Group>
<Item Text="About Us" AccessRoles="All">
<Group>
<Item Text="Option 1" AccessRoles="All" />
<Item Text="Option 2" AccessRoles="All" />
<Item Text="Option 3" AccessRoles="All" />
</Group>
</Item>
<Item Text="Projects" AccessRoles="All">
<Group>
<Item Text="Option 1" AccessRoles="All" />
<Item Text="Option 2" AccessRoles="Employee" />
<Item Text="Option 3" AccessRoles="Manager,Executive" />
</Group>
</Item>
<Item Text="Library" AccessRoles="Employee,Manager,Executive">
<Group>
<Item Text="Option 1" AccessRoles="Employee" />
<Item Text="Option 2" AccessRoles="Manager" />
<Item Text="Option 3" AccessRoles="Executive" />
</Group>
</Item>
</Group>
</Menu>
This xml is used for telerik RADMenu component and before I use it with
the control I want to read the document and remove any menu options
(<Item>) that the current logged in user does not have roles for.
At the point of reading/parsing the document I have a comma-delimited
string (or ArrayList) of roles assigned to the current user (including
role "All") and so I need to check to see if any of the roles exist in
the AccessRoles attribute for each item.
The problem I am having is in removing the nodes that do not meet the
criteria.
I have been going down the following route (please note that this code
is only checking for the "All" role)...
Public Shared Function GetRoleBasedMenuXml() As String
Dim strMenuXml As String
Dim xmldocMenu As XmlDocument
strMenuXml = HttpContext.Current.Cache.Get("PortMenuXML")
xmldocMenu = New XmlDocument
xmldocMenu.LoadXml(strMenuXml)
Dim xmlnlMenuItem As XmlNodeList =
xmldocMenu.GetElementsByTagName("Item")
For Each xmlNode As XmlNode In xmlnlMenuItem
If Not xmlNode.Attributes("AccessRoles") Is Nothing Then
If xmlNode.Attributes("AccessRoles").Value <> "All" Then
xmlNode.RemoveAll()
xmlNode.RemoveChild(xmlNode.Parent)
End If
End If
Next
Dim swFormattedMenuXML As StringWriter
swFormattedMenuXML = New StringWriter
xmldocMenu.Save(swFormattedMenuXML)
Return swFormattedMenuXML.ToString()
End Function
The problem with this is that the RemoveAll() method only removes the
child nodes and the current node attributes leaving <Item></Item>. I
have tried to use xmlNode.ParentNode.RemoveChild(xmlNode) after the
RemoveAll but this is invalid in a For Each loop! I have spent most of
my day trying to find different ways around this problem (XPath etc.)
but because it is variable depth and also the nature of the AccessRoles
validation it has proved unfruitful - I am missing something!
Any help/suggestions would be greatly appreciated!