Foreach Iteration Null

时间:2012-10-25 12:29:37

标签: c# linq sharepoint linq-to-xml

我正在使用LINQ过滤从Sharepoint WSS3的listService.GetListItems()方法返回的XmlNode。

这是它返回的XML: http://pastebin.com/mqHcserY

我发现最后一行与其他行不同,它不包含以下属性。

ows_ContentType
ows_LinkFilenameNoMenu
ows_LinkFilename
ows_BaseName 
ows__EditMenuTableStart

因此,请记住我使用LINQ过滤结果:

XmlNode items = listService.GetListItems(listName, string.Empty, query, viewFields, string.Empty, queryOptions, g.ToString());

// Namespace for z: prefix
XNamespace xns = "#RowsetSchema";

XElement root;
using (XmlReader xr = new XmlNodeReader(items)) { root = XElement.Load(xr); }

// This query returns XElements that are Folder types
IEnumerable<XElement> result = from child in root.Descendants(xns + "row")
                               where child.Attribute("ows_ContentType").Value != null && child.Attribute("ows_ContentType").Value == "Folder"
                               select child;

foreach (XElement xml in result)
{
    //Exception when attempts to loop final XElement
}

然而,当我迭代结果时,我得到NullReferenceException。在Foreach循环中,它将很乐意遍历每个对象,直到它到达最后一个对象,然后它将抛出异常。

这个最后一个对象是与其他行不同的对象(我通过消除过程知道这个,我看到每个其他行都循环过去)并且应该已经过滤掉了我的结果,因为它没有“ows_ContentType” “属性。

我将LINQ更改为where child.Attribute("ows_ContentType").Value != null && child.Attribute("ows_ContentType").Value == "Folder"以尝试过滤任何包含空值的内容,但结果相同。 我看了几个samples,我似乎有正确的语法。

有人可以解释导致这个最后一个XElement返回null的原因吗? 我真的不明白为什么它会在<IEnumerable<XElement> result集合中添加一个null实例。

4 个答案:

答案 0 :(得分:3)

调用非现有属性的值将导致空引用,因为该节点根本不存在。

child.Attribute("ows_ContentType").Value

通过调用缺少元素的值来抛出异常。

改为使用:

child.Attribute("ows_ContentType") != null

实现:

IEnumerable<XElement> result = from child in root.Descendants(xns + "row")
                           where child.Attribute("ows_ContentType") != null && child.Attribute("ows_ContentType").Value == "Folder"
                           select child;

答案 1 :(得分:2)

您需要检查元素是否为null而不是元素的值。

child.Attribute("ows_ContentType") != null && child.Attribute("ows_ContentType").Value == "Folder"

答案 2 :(得分:1)

请注意,LINQ2XML只允许您使用(string)someXElement(string)someXAttribute,如果XElement或XAttribute为null,则为null;如果存在,则为XElement或XAttribute的值。这意味着您可以缩短代码以使用

IEnumerable<XElement> result = from child in root.Descendants(xns + "row")
                               where (string)child.Attribute("ows_ContentType") == "Folder"
                               select child;

答案 3 :(得分:0)

最后一个节点不包含“ows_ContentType”属性,但您的where子句正在查找缺少属性的值。

可能你需要

where child.Attribute("ows_ContentType") != null 
&& child.Attribute("ows_ContentType").Value == "Folder"