LINQ to XML необязательный элемент запроса - PullRequest
14 голосов
/ 10 ноября 2008

Я работаю с существующим XML-документом, который имеет структуру (частично) примерно так:

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

Я использую LINQ to XML для запроса XDocument для получения всех этих записей следующим образом:

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

Элементы "ID" не всегда присутствуют, поэтому моим решением для этого был джаз Count () выше. Но мне интересно, есть ли у кого-то лучший способ сделать это. Я все еще чувствую себя комфортно с этим новым материалом и подозреваю, что может быть лучший способ сделать это, чем то, как я это делаю в настоящее время.

Есть ли лучший / более предпочтительный способ делать то, что я хочу?

Ответы [ 3 ]

23 голосов
/ 10 ноября 2008

XElement на самом деле имеет интересные явные операторы преобразования , которые в этом случае поступают правильно.

Таким образом, вам редко требуется доступ к свойству .Value.

Это все, что вам нужно для вашей проекции:

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

И если вы предпочитаете использовать значение ID в качестве целого числа в вашем анонимном типе:

var items =
    from g in xDocument.Root.Descendants("Group").Elements("Entry")
    select new
    {
        name = (string) g.Element("Name"),
        id = (int?) g.Element("ID"),
    };
3 голосов
/ 10 ноября 2008

В аналогичной ситуации я использовал метод расширения:

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

использование:

    id = g.OptionalElement("ID") ?? "none"
1 голос
/ 10 ноября 2008

Как насчет:

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

если это barfs, тогда FirstOrDefault() и т. Д. Могут быть полезны, иначе просто используйте метод расширения (как уже предлагалось).

...