【问题标题】:Linq To Xml Null Checking of attributesLinq To Xml Null 属性检查
【发布时间】:2010-12-02 15:47:59
【问题描述】:
<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
                                   };

我想知道是否有更好的方法来解决这个问题。

谢谢,

  • 贾里德

【问题讨论】:

    标签: c# linq linq-to-xml


    【解决方案1】:

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

    【讨论】:

    • 太棒了!我喜欢它。谢谢。
    【解决方案2】:

    使用扩展方法封装缺失的属性情况如何:

    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。如果类型转换失败,这将引发异常。如果您希望这些情况也返回默认值,则需要执行额外的错误处理。

    【讨论】:

    • 我在这个上使用了一个变体,但使用了XAttribute Attribute&lt;T&gt;(this XElement element, XName name, T defaultValue)。如果失败,请创建一个new XAttribute(name,defaultValue);。然后过载就在原来的旁边
    【解决方案3】:

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

    您可以阅读更多 here 部分标题为 Null 条件运算符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多