Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a complete list from a XML-file by using LINQ?

Tags:

c#

xml

linq

I have xml-file looks like this:

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

... and I want to create a list by using a LINQ-query.

 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();  

But I get a list of two items. First of each group.

But how I get a list looks this?

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

What do I have to change in my LINQ-query?

like image 491
user1531040 Avatar asked Dec 01 '25 08:12

user1531040


2 Answers

You need to flattern your hierarchy by using SelectMany Linq method or use Elements method, provided by LINQ to XML, which do the same job.

//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")
                             };

prints

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 is because your attribute in one Item has name as naeme. You also don't need AsQueryable here, as far as I can see.

As Chris kindly noted, you can use next code snippet to gather required nodes and then apply the same Select projection.

var nodes = XDocument.Parse(xml).Descendants("Item");
like image 159
Ilya Ivanov Avatar answered Dec 02 '25 20:12

Ilya Ivanov


Actually since your example is pretty simple, you can just get the Item nodes by calling Elements("Item") and use Parent to get the Group name:

    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();

Note I changed first call to Element() instead of Descendants() assuming per your example you only have one such element.

like image 44
Dmitriy Khaykin Avatar answered Dec 02 '25 22:12

Dmitriy Khaykin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!