Pergunta

Eu estou trabalhando com um documento XML existente, que tem uma estrutura (em parte) assim:

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

Eu estou usando LINQ to XML para consultar o XDocument para recuperar todas essas entradas da seguinte maneira:

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"
    };

Os elementos "ID" não são sempre lá e por isso a minha solução para este foi o Count () jazz acima. Mas eu estou querendo saber se alguém tem uma maneira melhor de fazer isso. Ainda estou ficando confortável com este material novo e eu suspeito que pode haver uma maneira melhor de fazer isso do que como atualmente estou fazendo isso.

Existe uma maneira melhor / mais preferido para fazer o que eu quero?

Foi útil?

Solução

XElement tem realmente operadores de conversão explícita interessantes que fazer a coisa certa no neste caso.

Assim, você raramente realmente precisa de acesso a propriedade .Value.

Este é tudo que você precisa para a sua projeção:

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

E se você preferir usar o valor de ID como um inteiro em seu 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"),
    };

Outras dicas

Em uma situação semelhante que eu usei um método de extensão:

    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"

Como sobre: ??

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;
            };

Se este Barfs, então FirstOrDefault() etc pode ser útil, caso contrário basta usar um método de extensão (como já foi sugerido).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top