2

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

5
  • have u tried if (AttrVal.FirstOrDefault() != null) by yourself before asking this question Commented May 9, 2014 at 14:42
  • @K.B - Yes I did, and I still got the same error. Commented May 9, 2014 at 14:44
  • in which line you are getting this error Commented May 9, 2014 at 14:46
  • @K.B - The if(!bool.TryParse ...) line. Commented May 9, 2014 at 14:49
  • You need to check that the attribute exists in your where before attempting to read its value - see: stackoverflow.com/a/2506840/61470 Commented May 9, 2014 at 14:51

3 Answers 3

1

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")
Sign up to request clarification or add additional context in comments.

3 Comments

Does this answer your question?
I implemented the AttrVal.Any() check in the if statement and it looks like that was the part I was missing.
sorry. I updated my answer a few minutes before your comment.
1

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"));
                }
            }

Comments

1

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"));
     }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.