Linq To Xml Null检查属性

时间:2010-12-02 15:48:00

标签: c# linq linq-to-xml

<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 个答案:

答案 0 :(得分:11)

您可以将属性转换为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")
            };

答案 1 :(得分:4)

如何使用扩展方法封装缺少的属性案例:

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。如果类型无法转换,这将抛出异常。如果您希望这些情况也返回默认值,则需要执行其他错误处理。

答案 2 :(得分:0)

在C#6.0中,您可以使用monadic Null条件运算符?. 在您的示例中应用它之后,它将如下所示:

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

您可以在标题为空条件运算符的部分中阅读更多here