node new net create crear con asp archivo c# linq linq-to-xml anonymous-types

c# - new - Consulta de elementos opcionales LINQ a XML



create node xmldocument (3)

En una situación similar usé un método de extensión:

public static string OptionalElement(this XElement actionElement, string elementName) { var element = actionElement.Element(elementName); return (element != null) ? element.Value : null; }

uso:

id = g.OptionalElement("ID") ?? "none"

Estoy trabajando con un documento XML existente que tiene una estructura (en parte) como esta:

<Group> <Entry> <Name> Bob </Name> <ID> 1 </ID> </Entry> <Entry> <Name> Larry </Name> </Entry> </Group>

Estoy usando LINQ to XML para consultar el XDocument para recuperar todas estas entradas de la siguiente manera:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry") select new { name = (string)g.element("Name").Value, id = g.Elements("ID").Count() > 0 ? (string)g.Element("ID").Value : "none" };

Los elementos de "ID" no siempre están ahí y mi solución a esto fue el jazz Count () anterior. Pero me pregunto si alguien tiene una mejor manera de hacer esto. Todavía me siento cómodo con estas cosas nuevas y sospecho que puede haber una mejor manera de hacerlo que cómo lo estoy haciendo actualmente.

¿Hay una forma mejor / más preferida de hacer lo que quiero?


Qué tal si:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry") let idEl = g.Element("ID") select new { name = (string)g.element("Name").Value, id = idEl == null ? "none" : idEl.Value; };

si esto es barfs, entonces FirstOrDefault() etc puede ser útil, de lo contrario simplemente use un método de extensión (como ya se sugirió).


XElement en realidad tiene operadores de conversión explícitos interesantes que hacen lo correcto en este caso.

Por lo tanto, rara vez necesita acceder a la propiedad .Value .

Esto es todo lo que necesita para su proyección:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry") select new { name = (string) g.Element("Name"), id = (string) g.Element("ID") ?? "none", };

Y si prefiere usar el valor de ID como un entero en su tipo anónimo:

var items = from g in xDocument.Root.Descendants("Group").Elements("Entry") select new { name = (string) g.Element("Name"), id = (int?) g.Element("ID"), };