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?
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");
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With