LINQ to XML: обработка узлов, которые не существуют? - PullRequest
3 голосов
/ 04 декабря 2009

Это может быть простое исправление (ну, вероятно, это так), но по какой-то причине я просто не могу понять это.

Итак, у меня есть xml, который выглядит примерно так:

XElement xml = XElement.Parse (
@"<Alphabet>
     <a name="A" />
     <b name="B" />
     <d name="D" />
     <e name="E" />
</Alphabet>");

Итак, позже в моем коде я ссылаюсь на узел, который может существовать или не существовать там, например:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault().Value;

Но когда он не существует, вместо возврата null или "" он генерирует исключение NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта.

Какой лучший способ проверить и проверить, существует ли узел в моем запросе linq? Или мне нужно проверить, существует ли какой-то другой способ?

Ответы [ 4 ]

5 голосов
/ 04 декабря 2009

Ну, вы выбираете атрибут - просто используйте:

var nameAttribute = xml.Descendants("c").Select(b => b.Attribute("name"))
                                        .FirstOrDefault();
if (nameAttribute != null)
{
    string name = nameAttribute.Value;
}
else
{
    // Whatever...
}

(Я изменил его с выражения запроса на точечную нотацию, потому что запрос был тривиальным - синтаксис выражения запроса фактически ничего вам не купил.)

Одна проблема с этим решением: оно не делает различий между тем, что существует элемент "c", но у него нет атрибута "name", и что вначале не было элемента "c". Вам нужно уметь отличить?

4 голосов
/ 04 декабря 2009

Я создал методы расширения, чтобы сделать это для меня.

public static string GetAttributeValue(this XElement element, string attributeName)
{
    XAttribute attribute = element.Attribute(attributeName);
    return attribute != null ? attribute.Value : string.Empty;
}

public static string GetElementValue(this XElement element)
{
    return element != null ? element.Value : string.Empty;
}

public static string GetElementValue(this XElement element, string elementName)
{
    XElement child = element.Element(elementName);
    return child != null ? child.Value : string.Empty;
}
1 голос
/ 05 декабря 2009

FirstOrDefault возвращает null или XAttribute, которые можно привести к string, чтобы получить значение:

var name = (string)((from b in xml.Descendants("c")
                     select b.Attribute("name")).FirstOrDefault());

или

var name = (string)xml.Descendants("c")
                      .Select(b => b.Attribute("name"))
                      .FirstOrDefault();
0 голосов
/ 04 декабря 2009

Вы можете сделать что-то вроде этого:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name").Value).FirstOrDefault();

или если вам действительно нужен элемент:

var name = (from b in xml.Descendants("c")
            select b.Attribute("name")).FirstOrDefault();

if (name != null)
{
    // your logic ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...