Get Attribute Value by LINQ

getelementbyid html-agility-pack linq

Question

The HTML Source is as follows

<img id="itemImage" src="https://www.xyz.com/item1.jpg">

I am using the following LINQ query to get the SRC value (Image Link)

string imageURL = document.DocumentNode.Descendants("img")
                    .Where(node => node.Attributes["id"] != null && node.Attributes["id"].Value == "itemImage")
                    .Select(node => node.Attributes["src"].Value).ToString();

But the imageURL gives output as

System.Linq.Enumerable+WhereSelectEnumerableIterator`2[HtmlAgilityPack.HtmlNode,System.String]

Accepted Answer

The problem is casting it to string. Select() returns IEnumerable<T> so you are basically converting an enumerator to a string (as the error message says). Call First() or Single() or Take(1) in order to get a single element before casting it to a string.

.Select(node => node.Attributes["src"].Value).First().ToString();

Also, if there is a chance that the desired element is not present, FirstOrDefault() and SingleOrDefault() returns null rather then throwing an exception. In that case, I would recommend

var imageUlr = ... .Select(node => node.Attributes["src"].Value).FirstOrDefault();
if (imageUrl != null)
{
    // cast it to string and do something with it
}

Popular Answer

Add .DefaultIfEmpty(string.Empty) .FirstOrDefault

string imageURL = document.DocumentNode.Descendants("img")
                .Where(node => node.Attributes["id"] != null && node.Attributes["id"].Value == "itemImage")
                .Select(node => node.Attributes["src"].Value)
                .DefaultIfEmpty(string.Empty)
                .FirstOrDefault()
                .ToString();



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why