2011-06-29 89 views
0

我有這個XML文件,我解析到它的元素並創建一個自定義對象模塊的列表。XML linq查詢列出第一個元素,但不是全部

XDocument kobra = XDocument.Load(new StringReader(results.OuterXml)); 
XNamespace ns = "#RowsetSchema"; 

var kobraNodeList = from s in kobra.Descendants(ns + "row") 
        select new Module 
        { 
         id = s.Attribute("ows_ID").Value, 
         name = s.Attribute("ows_Title").Value, 
         sourceFile = s.Attribute("ows_Source_x0020_Message_x0020_File_").Value, 
         scope = Scope.KOBRA, 
         component = string.Empty 
        }; 

,這裏是我的模塊結構:

public struct Module 
{ 
    public string name; 
    public Scope scope; 
    public string component; 
    public int wordCound; 
    public string id; 
    public string sourceFile; 
} 

的代碼工作正常,但事情變得奇怪,當我嘗試了var kobraNodeList轉換成模塊的列表,我在AddRange得到System.NullReferenceException行:

this.moduleList = new List<Module>; 
this.moduleList.AddRange(kobraNodeList); 

當試圖調試,我注意到,雖然kobraNodeList.Count()也返回System.NullReferenceException,一個kobraNodeList.Any()返回truekobraNodeList.First()返回一個完美有效和正確的模塊結構與所需的數據。

的XML文件是有效的,如果我更換與此LINQ查詢:

var kobraNodeList = from s in kobra.Descendants(ns + "row") 
        select s; 

我得到的XElement的有效列表,我可以Count()確定。 有人可以解釋我有什麼問題嗎?順便說一句,我使用.NET 3.5。

回答

3

看起來像kobra.Descendants中的一個(或多個)有ows_ID,ows_Titleows_Source_x0020_Message_x0020_File_屬性缺失。

Linq使用deferred execution,所以它不會嘗試構建序列,直到您要求項目。當您調用Any()或First()時,它只需要序列中的第一個項目工作,這告訴我kobra.Descendants中的第一個項目確實具有所有必需的節點。

但是,第一個項目之後的其中一個項目可能缺少至少一個這樣的屬性 - 因此您最終要求獲得NULL屬性的Value

2

select new Module 
{ 
    // properties... 
} 

你可能會運行到一個NullReferenceException因爲你可能不會在XML文檔中存在的元素訪問.Value。您收集的第一個對象可能沒有問題,因此您在使用Any()First()時會得出結果。後續項目可能會丟失您嘗試使用的元素/屬性。

試試用這個代替直接使用.Value

id = (string)s.Attribute("whatever") // etc. 
+0

Holy sh **你是對的,我100%肯定XML文件是完整的所有屬性,不可能是原因。謝謝! – Antoine

0

一個你的線條,如s.Attribute("ows_Source_x0020_Message_x0020_File_")將用於的記錄,以便s.Attribute("ows_Source_x0020_Message_x0020_File_").Value之一返回null將導致空引用異常。