Linq To Xml Null Проверка атрибутов - PullRequest
10 голосов
/ 02 декабря 2010
<books>
   <book name="Christmas Cheer" price="10" />
   <book name="Holiday Season" price="12" />
   <book name="Eggnog Fun" price="5" special="Half Off" />
</books>

Я бы хотел разобрать это с помощью linq, и мне любопытно, какие методы используют другие люди для обработки специальных сообщений. Мой текущий способ работы с этим:

var books = from book in booksXml.Descendants("book")
                        let Name = book.Attribute("name") ?? new XAttribute("name", string.Empty)
                        let Price = book.Attribute("price") ?? new XAttribute("price", 0)
                        let Special = book.Attribute("special") ?? new XAttribute("special", string.Empty)
                        select new
                                   {
                                       Name = Name.Value,
                                       Price = Convert.ToInt32(Price.Value),
                                       Special = Special.Value
                                   };

Мне интересно, есть ли лучшие способы решить эту проблему.

Спасибо

  • Джаред

Ответы [ 3 ]

11 голосов
/ 02 декабря 2010

Вы можете привести атрибут к string. Если он отсутствует, вы получите null, и последующий код должен проверить на null, иначе он вернет значение напрямую.

Попробуйте вместо этого:

var books = from book in booksXml.Descendants("book")
            select new
            {
                Name = (string)book.Attribute("name"),
                Price = (string)book.Attribute("price"),
                Special = (string)book.Attribute("special")
            };
4 голосов
/ 02 декабря 2010

Как насчет использования метода расширения для инкапсуляции пропущенных случаев атрибута:

public static class XmlExtensions
{
    public static T AttributeValueOrDefault<T>(this XElement element, string attributeName, T defaultValue)
    {
        var attribute = element.Attribute(attributeName);
        if (attribute != null && attribute.Value != null)
        {
            return (T)Convert.ChangeType(attribute.Value, typeof(T));
        }

        return defaultValue;
    }
}

Обратите внимание, что это будет работать, только если T - это тип, в который строка преобразуется через IConvertible. Если вы хотите поддерживать более общие случаи преобразования, вам, возможно, придется поискать TypeConverter. Это вызовет исключение, если тип не преобразуется. Если вы хотите, чтобы эти случаи также возвращали значение по умолчанию, вам потребуется выполнить дополнительную обработку ошибок.

0 голосов
/ 06 сентября 2015

В C # 6.0 вы можете использовать монадический нуль-условный оператор ?. После применения в вашем примере это будет выглядеть так:

var books = from book in booksXml.Descendants("book")
            select new
            {
                Name = book.Attribute("name")?.Value ?? String.Empty,
                Price = Convert.ToInt32(book.Attribute("price")?.Value ?? "0"),
                Special = book.Attribute("special")?.Value ?? String.Empty
            };

Вы можете прочитать больше здесь inчасть под названием Null-условные операторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...