Reputation: 3201
I have an XML file for settings. Here is an example with a few elements:
<Settings>
<Templates>
<Item name="Home" value="{B0BDB6B6-CB6E-464A-A170-6F88E2B3B10F}" />
<Item name="DevelopmentLanding" value="{3F66C5BA-BE16-4E29-A9D8-0FFBCEA4C791}" />
<Item name="EventsLanding" value="{A1D51F12-D449-4933-8C0E-B236F291D050}" />
</Templates>
<Application>
<Item name="MemberDomain" value="extranet" />
<Item name="SearchCacheHours" value="0" />
<Item name="SearchCacheMinutes" value="10" />
</Application>
</Settings>
I also have two classes:
public class Setting
{
public string Type { get; set; }
public IEnumerable<SettingItem> SettingItems { get; set; }
}
and
public class SettingItem
{
public string Name { get; set; }
public string Value { get; set; }
}
I want to take the XML file and strongly type it using my two classes, so then I'd end up with a List<Setting>
.
This is the code I have so far to do this:
var xml = XDocument.Load(HttpContext.Current.Server.MapPath(AppConfig.SettingsFileLocation));
var root = xml.Root;
var toplevel = root.Elements().AsEnumerable()
.Select(item => new Setting
{
Type = item.Name.ToString(),
SettingItems = item.Elements(item.Name.ToString()).AsEnumerable()
.Select(x => new SettingItem
{
Name = x.Attribute("name").ToString(),
value = x.Attribute("value").ToString()
}
).ToList()
});
However, when I run this, I don't have anything in Setting.SettingItems
.
Where am I going wrong?
Upvotes: 1
Views: 109
Reputation: 8850
Have you considered another approach to LINQ? For example, you could generate strongly typed classes using xsd.exe
, as described in this answer. Loading the data from the XML could be done via deserialization, example in this answer.
Side note: the XML is badly formed XML (the last line should be </Settings>
).
Upvotes: 1
Reputation: 3065
Your problem is the line:
SettingItems = item.Elements(item.Name.ToString()).AsEnumerable()
it should read:
SettingItems = item.Elements()
You want all the child elements of item (the "Templates" or "Application" node), not the ones also named "Templates" or "Application". The AsEnumerable is just unnecessary, since Elements() returns an IEnumerable already.
Upvotes: 0
Reputation: 1738
I'm not sure why your code isn't working, but something like this should work:
var toplevel = doc.Root.Elements().Select(settingElement => new Setting
{
Type = settingElement.Name.LocalName,
SettingItems = settingElement.Elements("Item").Select(itemElement => new SettingItem
{
Name = itemElement.Attribute("name").Value,
Value = itemElement.Attribute("value").Value,
})
}).ToList();
Upvotes: 1