Domanda

Sto lavorando con un documento XML esistente che ha una struttura (in parte) in questo modo:

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

Sto usando LINQ to XML per interrogare XDocument per recuperare tutte queste voci come segue:

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

L'ID " " gli elementi non sono sempre presenti e quindi la mia soluzione è stata il Count () jazz sopra. Ma mi chiedo se qualcuno ha un modo migliore per farlo. Mi sto ancora sentendo a mio agio con queste nuove cose e sospetto che potrebbe esserci un modo migliore per farlo rispetto a come lo sto attualmente facendo.

Esiste un modo migliore / più preferito per fare ciò che voglio?

È stato utile?

Soluzione

XElement attualmente ha operatori di conversione esplicita interessanti che fanno la cosa giusta in questo caso.

Quindi raramente è necessario accedere alla proprietà .Value .

Questo è tutto ciò che serve per la tua proiezione:

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 preferisci utilizzare il valore di ID come numero intero nel tuo tipo anonimo:

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

Altri suggerimenti

In una situazione simile ho usato un metodo di estensione:

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

utilizzo:

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

Che ne dici di:

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 questo barfs, allora FirstOrDefault () ecc potrebbe essere utile, altrimenti basta usare un metodo di estensione (come già suggerito).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top