LINQ查询返回null结果

时间:2011-10-15 17:53:01

标签: linq linq-to-objects web-scraping nodes

我有以下代码

nodes = data.Descendants(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Results")).Nodes();
        System.Collections.Generic.IEnumerable<Result> res = new List<Result>();
        if (nodes.Count() > 0)
        {
            var results = from uris in nodes
                          select new Result
        {
            URL =
((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Url")).Value,
            Title =
((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Title")).Value,
            Description =
((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Description")).Value,
            DateTime =
((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}DateTime")).Value,
        };
            res = results;
        }

结果是一个对象,其中定义了URL,Title,Description和DateTime变量。

这一切都正常工作,但是当节点中的“节点”不包含Description元素(或者至少我认为那是什么抛出它)时,程序会点击“res = results;” 代码行并抛出'对象引用未设置为...'错误并在“选择新结果”之后突出显示整个部分..

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

最简单的方法是转换为string,而不是使用Value属性。这样,您最终会得到null的{​​{1}}引用。

但是,您的代码也可以更好地批次

Description

看看有多简单? Techiques使用:

  • 在空序列上调用XNamespace ns = "http://schemas.microsoft.com/LiveSearch/2008/04/XML/web"; var results = data.Descendants(ns + "Results") .Elements() .Select(x => new Result { URL = (string) x.Element(ns + "Url"), Title = (string) x.Element(ns + "Title"), Description = (string) x.Element(ns + "Description"), DateTime = (string) x.Element(ns + "DateTime") }) .ToList(); 会为您提供一个列表
  • 这样你只会执行一次查询;在你调用ToList()之前,它可能会遍历每个节点。通常,使用Count()代替Any() - 但这次只是使列表无条件更简单。
  • 使用Count() > 0)方法获取子元素,而不是多次转换。 (如果遇到任何非元素节点,您以前的代码会抛出异常)
  • 使用从字符串隐式转换为Elements()
  • 使用XNamespace运算符获取+(XNamespace, string)

答案 1 :(得分:1)

如果未包含Description元素,则应测试此

((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Description"))
使用Value之前

不为null。试试这段代码:

var results = from uris in nodes let des = ((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Description"))
                      select new Result
    {
        URL = ((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Url")).Value,
        Title = ((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}Title")).Value,
        Description = (des != null) ? des.Value : string.Empty,
        DateTime = ((XElement)uris).Element(XName.Get("{http://schemas.microsoft.com/LiveSearch/2008/04/XML/web}DateTime")).Value,
    };