2013-03-20 71 views
2

我的XML文件是這樣的:如何使用LINQ從XML文件獲取完整列表?

<Knowledge> 
    <Group name="Methods and Techniques"> 
    <Item name="OO" level="1" /> 
    <Item name="Dataflow Diagram" level="4" /> 
    <Item naeme="SDM" level="5" /> 
    </Group> 
    <Group name="Languages"> 
    <Item name="C#" level="1" /> 
    <Item name="Delphi" level="1" /> 
    <Item name="Visual Basic" level="4" /> 
    </Group> 
</Knowledge> 

...我想通過使用LINQ查詢創建一個列表。

var queryKnowledge = (from item in _Document.Descendants("Knowledge").Elements("Group") 
          select new 
          { 
           Group = (string)item.Attribute("name"), 
           Name = (string)item.Element("Item").Attribute("name"), 
           Level = (string)item.Element("Item").Attribute("level") 
          }).AsQueryable(); 

但我得到了兩個項目的列表。每個組的第一個。

但是我如何得到一個列表看起來這樣?

Group     Name    Level 
Methods and Techniques OO    1 
Methods and Techniques Dataflow Diagram 4 
Methods and Techniques SDM    5 
Languages    C#    1 
Languages    Delphi   1 
Languages    Visual Basic  4 

我在LINQ查詢中需要更改什麼?

回答

7

您需要通過使用SelectMany Linq方法或使用LINQ to XML提供的Elements方法來扁平化您的層次結構,該方法執行相同的工作。

//xml variable contains string representation of your xml 
//use XDocument.Load(filePath) to load xml having path to a file 
var nodes = XDocument.Parse(xml) 
        .Descendants("Knowledge") 
        .Elements("Group") 
        .Elements("Item"); 

var queryKnowledge = from item in nodes 
          select new 
          { 
           Group = (string)item.Parent.Attribute("name"), 
           Name = (string)item.Attribute("name"), 
           Level = (string)item.Attribute("level") 
          }; 

打印

Group     Name    Level 
Methods and Techniques OO    1 
Methods and Techniques Dataflow Diagram 4 
Methods and Techniques null    5 
Languages    C#    1 
Languages    Delphi   1 
Languages    Visual Basic  4 

null是因爲在一個項目的屬性有名稱naeme。就我所見,您也不需要AsQueryable

正如Chris所說,您可以使用下一個代碼片段來收集所需的節點,然後應用相同的Select投影。

var nodes = XDocument.Parse(xml).Descendants("Item"); 
+0

+1父元素的巧妙使用 – 2013-03-20 11:05:43

+2

您也可以只選擇_Document.Descendants(「Item」),假設這是整個模式。 – 2013-03-20 11:11:42

+0

@ChrisMcAtackney +1,謝謝,將更新我的回答 – 2013-03-20 11:13:01

3

事實上,因爲你的例子是非常簡單的,你可以通過調用Elements("Item")得到Item節點和使用parent獲得組名稱:

var queryKnowledge = (from item in xDoc.Element("Knowledge").Elements("Group").Elements("Item") 
          select new 
          { 
           Group = (string)item.Parent.Attribute("name"), 
           Name = (string)item.Attribute("name"), 
           Level = (string)item.Attribute("level") 
          }).AsQueryable(); 

注意我改變了第一次調用元素()而不是後代()假設你的例子只有一個這樣的元素。

+0

好的解決方案。它看起來很簡單。 – user1531040 2013-03-20 11:26:29

相關問題