2012-10-25 89 views
3

我使用LINQ來過濾從Sharepoint WSS3的listService.GetListItems()方法返回的XmlNode。Foreach迭代空

這是它返回的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集合中。

+0

你是否在您的循環中修改了所有節點? – Rawling

+3

怎麼樣在哪兒child.Attribute(「ows_ContentType」)!= null而不是調用值?從一個不存在的節點調用值將會拋出一個異常 – middelpat

+0

啊,這很有道理。 Muchas gracias! – Amicable

回答

3

調用一個不存在的屬性值將導致nullreference,因爲節點根本不存在。

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

您需要檢查元素是否爲空而不是元素的值。

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

我的觀點正是:) – middelpat

0

的最後一個節點不包含「ows_ContentType」屬性,但你的where子句尋找那個失蹤屬性的值。

可能需要

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

_Really_確保child.Attribute(「ows_ContentType」)不爲空:) – Rawling

+0

爲了我自己的興趣,根據這個答案,如果子句發現條件導致false ?否則,當它檢查節點爲空時,它也會請求該值,並檢查是否爲null導致執行,因爲該節點爲空? – middelpat

+0

@Rawlin:哦,那是怎麼進去的? –

1

注意LINQ2XML只是允許您使用(string)someXElement(string)someXAttribute這將給空當的XElement或XAttribute爲空或價值XElement或XAttribute(如果存在)。這意味着你的代碼可以縮短使用

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