Reputation: 5619
I'm not the best a Linq and I have written the below query and it just seems my where clause is redundant and there has to be a better way?
Given the following XML structure:
<Views>
<Fulfillment>
<SecurityRoleName>ABCD</SecurityRoleName>
<SecurityRoleViews>
<RoleView name="A" />
<RoleView name="B" />
<RoleView name="C" />
<RoleView name="D" />
<RoleView name="E" />
<RoleView name="F" />
</SecurityRoleViews>
<PublicRoleViews>
<RoleView name="Z" />
<RoleView name="Y" />
<RoleView name="X" />
<RoleView name="W" />
<RoleView name="V" />
<RoleView name="U" />
</PublicRoleViews>
</Fulfillment>
</Views>
I wrote the following to get a single value (FulfillmentRoleName) and two List (SecuredViews, PublicViews) objects.
FulfillmentRoleName = configParms.Descendants("Fulfillment")
.Where(node => (string)node.Element("SecurityRoleName") == "SecurityRoleName")
.Select(node => node.Value.ToString())
.First();
SecuredViews = configParms.Descendants("SecurityRoleViews")
.Where(node => (string)node.Element("RoleView") == "RoleView")
.Select(node => node.Attribute("name").Value.ToString())
.ToList();
PublicViews = configParms.Descendants("PublicRoleViews")
.Where(node => (string)node.Element("RoleView") == "RoleView")
.Select(node => node.Attribute("name").Value.ToString())
.ToList();
I would want the following values:
FulfillmentRoleName = ABCD
SecuredViews = List of names A,B,C...
PublicViews = List of names Z,Y,X....
It is the where clause that I am unsure of:
.Where(node => (string)node.Element("RoleView") == "RoleView")
Seems there has to be a more elegant way to locate that node?
Thank you for taking the time to help
As per Ahmad Mageed recommendation I am using the more elegant Element("") approach. However I am getting an instantiation error...as if the element collection is not built yet??
However if I use configParms.Root.Value I get my SecurityRoleName value???
I would have thought that views would be the root....or is it the first node that has a value???
Upvotes: 1
Views: 42
Reputation: 96497
You can use the Elements
method and provide the name to match. This would allow you to replace the where query with Elements("RoleView")
.
Some other observations:
Element
method, instead of Descendants
.Value
property returns a string. The ToString()
calls are redundant.Here's an updated version of your queries:
// if configParms is an XDocument use configParms.Root
var securityRoleName = configParms.Element("Fulfillment")
.Element("SecurityRoleName").Value;
var securedViews = configParms.Descendants("SecurityRoleViews")
.Elements("RoleView")
.Select(node => node.Attribute("name").Value)
.ToList();
var publicViews = configParms.Descendants("PublicRoleViews")
.Elements("RoleView")
.Select(node => node.Attribute("name").Value)
.ToList();
Upvotes: 1