Yoav
Yoav

Reputation: 2077

C# Linq to XML - simple query returns no results

I have this XML which contains a list of entities:

<?xml version="1.0" encoding="utf-8" ?>
<Connections>
  <Connection>
    <ConnectionName>connName</ConnectionName>
    <InterfaceName>Account Lookup</InterfaceName>
    <RequestFolder>C:\Documents and Settings\user\Desktop\Requests</RequestFolder>
    <ResponseFolder>C:\Documents and Settings\user\Desktop\Responses</ResponseFolder>
  </Connection>
</Connections>

I'm trying to retrive one of them based on its name and build an object from it.

var results = (from i in this.Elements("Connection")
                           where i.Element("ConnectionName").ToString() == stubConnectionName
                           select new {
                               interfaceName = ((string)i.Element("InterfaceName").Value),
                               requestFolder = ((string)i.Element("RequestFolder").Value),
                               responseFolder = ((string)i.Element("ResponseFolder").Value),
                           }).Single();

return new StubConnection(stubConnectionName, results.interfaceName, results.requestFolder, results.responseFolder);

The problem is that results comes back empty. What is wrong with my query?

Upvotes: 1

Views: 177

Answers (1)

Adam
Adam

Reputation: 15805

where i.Element("ConnectionName").ToString() == stubConnectionName

has to be:

where i.Element("ConnectionName").Value == stubConnectionName

because XElement.ToString returns <ConnectionName>connName</ConnectionName> including the XML tags, while XElement.Value only returns the enclosed connection name without the tags.

By the way, you are unnecessarily casting all the values (which are already of type string) to string. You can simplify that:

var results = (from i in this.Elements("Connection")
               where i.Element("ConnectionName").Value == stubConnectionName
               select new
               {
                   interfaceName = i.Element("InterfaceName").Value,
                   requestFolder = i.Element("RequestFolder").Value,
                   responseFolder = i.Element("ResponseFolder").Value,
               }).Single();

You could even go one step further and directly select and return your result, without using an anonymous type in between:

return (from i in this.Elements("Connection")
        where i.Element("ConnectionName").Value == stubConnectionName
        select new StubConnection(stubConnectionName,
                                  i.Element("InterfaceName").Value,
                                  i.Element("RequestFolder").Value,
                                  i.Element("ResponseFolder").Value)).Single();

Please also understand the differences of

XElement.Value vs (string)XElement

Be careful when calling the Value property directly, as it will throw an Exception if the element contains no value. Cast the element (not the Value, but the XElement directly) to string if you are not sure whether it will contain a value. If it doesn't, null will be returned; otherwise, the result is the same.

Upvotes: 6

Related Questions