问题
I am trying to extract information from an XML file into an object using LINQ to XML. Although I can return the document and section Id attributes I cannot get access to the Items for each section element, it returns an IEnumerable of all the items in the document. I know this is correct as I’m calling Descendants but am struggling to get it to return only the child items of each section element. Can anybody help?
XML Document
<root>
<document id="1">
<section id="1.1">
<item id="1.1.1"></item>
<item id="1.1.2"></item>
<item id="1.1.3"></item>
</section>
<section id="1.2">
<item id="1.2.1"></item>
<item id="1.2.2"></item>
</section>
</document>
</root>
LINQ Query
XElement documentRoot = XElement.Load("document.xml");
var documents = (from docs in documentRoot.Descendants("document")
select new
{
Id = (string) docs.Attribute("id"),
Sections = docs.Elements("section"),
Items = docs.Elements("section").Elements("item")
}).ToList();
foreach(var doc in documents)
{
foreach(var section in doc.Sections)
{
Console.WriteLine("SectionId: " + section.Attribute("Id"));
foreach(var item in doc.Items)
{
Console.WriteLine("ItemId: " + section.Attribute("Id"));
}
}
}
回答1:
You got some small typos, on attribute Id
and at item loop. But if you're trying to get all section items into that items collection, you're wrong at design level, as Items
should be a Section
property, not Document
(so you'll need to query your XML twice).
Or, you can to do something like:
var documents =
(from docs in documentRoot.Descendants("document")
select new
{
Id = (string) docs.Attribute("id"),
Sections = docs.Elements("section")
}).ToList();
foreach (var doc in documents)
{
foreach (var section in doc.Sections)
{
Console.WriteLine("SectionId: " + section.Attribute("id"));
foreach (var item in section.Elements("item"))
{
Console.WriteLine("ItemId: " + item.Attribute("id"));
}
}
}
Output:
SectionId: id="1.1" ItemId: id="1.1.1" ItemId: id="1.1.2" ItemId: id="1.1.3" SectionId: id="1.2" ItemId: id="1.2.1" ItemId: id="1.2.2"
回答2:
Do you want a flat structure ?!?! (from LinqPad)
XElement documentRoot = XElement.Parse (
@"<root>
<document id='1'>
<section id='1.1'>
<item id='1.1.1'></item>
<item id='1.1.2'></item>
<item id='1.1.3'></item>
</section>
<section id='1.2'>
<item id='1.2.1'></item>
<item id='1.2.2'></item>
</section>
</document>
</root>
");
var documents = (from docs in documentRoot.Descendants("section")
select new
{
SectionId = (string) docs.Attribute("id"),
Items = docs.Elements("item")
});
documents.Dump();
This gives 2 SectionId
items that containes XElement
s with related items.
来源:https://stackoverflow.com/questions/2089799/linq-to-xml-selecting-child-elements