2013-03-20 77 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

相关问题