Obtener valor de atributo por LINQ

getelementbyid html-agility-pack linq

Pregunta

La fuente HTML es la siguiente

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

Estoy utilizando la siguiente consulta LINQ para obtener el valor SRC (Enlace de imagen)

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

Pero el imageURL da salida como

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

Respuesta aceptada

El problema es echarlo a la cuerda. Select() devuelve IEnumerable<T> por lo que básicamente está convirtiendo un enumerador en una cadena (como lo indica el mensaje de error). Llame a First() o Single() o Take(1) para obtener un solo elemento antes de convertirlo en una cadena.

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

Además, si existe la posibilidad de que el elemento deseado no esté presente, FirstOrDefault() y SingleOrDefault() devuelven un valor nulo en lugar de lanzar una excepción. En ese caso, recomendaría

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

Respuesta popular

Añadir .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();


Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué