質問

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??

enter image description here

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???

役に立ちましたか?

解決

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:

  • You can simplify the first query by grabbing the "Fulfillment" element directly by using the Element method, instead of Descendants.
  • The 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();
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top