2010-12-02 10 views
10
<books> 
    <book name="Christmas Cheer" price="10" /> 
    <book name="Holiday Season" price="12" /> 
    <book name="Eggnog Fun" price="5" special="Half Off" /> 
</books> 

Me gustaría analizar esto utilizando linq y me gustaría saber qué métodos usan otras personas para manejarlos. Mi forma actual de trabajar con esto es:Linq To Xml Null Comprobación de los atributos

var books = from book in booksXml.Descendants("book") 
         let Name = book.Attribute("name") ?? new XAttribute("name", string.Empty) 
         let Price = book.Attribute("price") ?? new XAttribute("price", 0) 
         let Special = book.Attribute("special") ?? new XAttribute("special", string.Empty) 
         select new 
            { 
             Name = Name.Value, 
             Price = Convert.ToInt32(Price.Value), 
             Special = Special.Value 
            }; 

Me pregunto si hay mejores formas de solucionar esto.

Gracias,

  • Jared

Respuesta

11

Puede convertir el atributo en string. Si está ausente obtendrá null y el código subsiguiente debe verificar null, de lo contrario devolverá el valor directamente.

Tal vez puedas probar:

var books = from book in booksXml.Descendants("book") 
      select new 
      { 
       Name = (string)book.Attribute("name"), 
       Price = (string)book.Attribute("price"), 
       Special = (string)book.Attribute("special") 
      }; 
+0

¡Eso es increíble! Lo amo. Gracias. – Howel

4

¿Cómo sobre el uso de un método de extensión para encapsular los casos de atributos que faltan:

public static class XmlExtensions 
{ 
    public static T AttributeValueOrDefault<T>(this XElement element, string attributeName, T defaultValue) 
    { 
     var attribute = element.Attribute(attributeName); 
     if (attribute != null && attribute.Value != null) 
     { 
      return (T)Convert.ChangeType(attribute.Value, typeof(T)); 
     } 

     return defaultValue; 
    } 
} 

Tenga en cuenta que esto sólo funcionará si T es un tipo a lo que la cadena sabe convertir a través de IConvertible. Si desea admitir casos de conversión más generales, también deberá buscar un TypeConverter. Esto generará una excepción si el tipo no puede convertirse. Si desea que esos casos también devuelvan el valor predeterminado, deberá realizar un control de errores adicional.

+0

Utilicé una variante en este caso, pero usé 'XAttribute Attribute (este elemento XElement, XName name, T defaultValue)'. Si falla, cree un 'nuevo XAttribute (name, defaultValue);'. Entonces la sobrecarga está allí junto con la original –

0

En C# 6.0 se puede utilizar monádico operador nulo condicional ?. Después de aplicarlo en su ejemplo se vería así:

var books = from book in booksXml.Descendants("book") 
      select new 
      { 
       Name = book.Attribute("name")?.Value ?? String.Empty, 
       Price = Convert.ToInt32(book.Attribute("price")?.Value ?? "0"), 
       Special = book.Attribute("special")?.Value ?? String.Empty 
      }; 

Usted puede leer más here en parte titulado Operadores Null-conditional.

Cuestiones relacionadas