Question

This is my XML:

<configuration>
    <Script name="Test Script">
        <arguments>
            <argument key="CheckStats" value="True" />
            <argument key="ReferenceTimepoint" value="SCREENING" />
            <argument key="outputResultSetName" value="ResultSet" />
        </arguments>
    </Script>
</configuration>

I am trying to use this linq statement to grab an argument element's value attrbiute if a specific key attribute exists.

XElement root = XElement.Load(configFileName);
var AttrVal = from el in root.Elements("Script").Elements("arguments").Elements("argument")
            where el.Attribute("key").Value == "CheckStats"
            select el.Attribute("value").Value;

Then I want to try and parse the attribute value into a boolean:

bool checkVal;
if (AttrVal != null)
{
    if (!bool.TryParse(AttrVal.First().ToString(), out checkVal))
    {
        throw new Exception(string.Format("Invalid value"));
    }
}

This code works if there is an element with that attribute, but if there isn't one, I get a System.InvalidOperationException: Sequence contains no elements.

How can I get around that? I thought by checking if (AttrVal != null) it would work. Should I replace that with if (AttrVal.FirstOrDefault() != null) or something similar? Thanks

Était-ce utile?

La solution

In if statement, you can write

if (AttrVal != null && AttrVal.Any())

EDIT: I'm wrong. The exception should come from First(), not any of Elements(). Old answer:

from el in root.Descendants("argument")

Or

from el in root.XPathSelectElements("./Script/arguments/argument")

Autres conseils

you have to check if there is already your attribute in the element where el.Attributes("key")!=null&&

XElement root = XElement.Load("config.xml");
            var AttrVal = from el in root.Elements("Script").Elements("arguments").Elements("argument")
                          where el.Attributes("key")!=null&&  el.Attribute("key").Value == "CheckStats"
                          select el.Attribute("value").Value;

            bool checkVal;
            if (AttrVal != null)
            {
                if (!bool.TryParse(AttrVal.First().ToString(), out checkVal))
                {
                    throw new Exception(string.Format("Invalid value"));
                }
            }

Here's a way to eliminate those pesky null checks - seek ahead with XPath to determine whether a node with both the necessary attributes (viz key="CheckStats" AND a value) exists, then parse it.

     bool checkVal;

     // using System.Xml.XPath;!
     var el = root.XPathSelectElement(
                    "/Script/arguments/argument[@key='CheckStats' and @value]");
     if (el != null && !bool.TryParse(el.Attribute("value").Value, 
         out checkVal))
     {
        throw new Exception(string.Format("Invalid value"));
     }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top