Parsing XML with LINQ in C#
我正在尝试使用LINQ在C#和XML之间进行映射。当前,我有一个用C#定义的类,如下所示:
Item.cs
1 2 3 4 5 6 7 8 | public class Item { public string DepartmentName { get; set; } public Dictionary<string, string> DepartmentNames { get; set; } public string Name { get; set; } public Dictionary<string, string> Names { get; set; } } |
我的XML文件如下所示:
departments.xml
1 2 3 4 5 6 7 8 9 10 11 | <Departments> <Department Name="Sports" Title="Sports Department" Path="/sports" en-us="Sports" de-de="Sport"> <Item Name="Football" en-us="Football" de-de="Fu?ball" es-mx="" /> <Item Name="TennisBall" en-us="Tennis Ball" de-de="Tennisball" /> </Department> <Department Name="Automotive" Title="Automotive Department" Path="/autos" en-us="Automotive" de-de="kraftfahrtechnisch"> <Item Name="Oil" en-us="Oil" de-de="?l" /> <Item Name="Tires" en-us="Tires" de-de="Bereifung" es-mx="Ruedas" /> </Department> </Departments> |
基本上,我有一些要加载到确定属性中的值。然后,我有一个我想加载到字典中的属性列表(" zh-cn"," de-de"," es-mx")。当前,我有以下内容:
1 2 3 4 5 6 7 8 9 10 11 | var items = XDocument.Parse(File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"App_Data\\Items.xml"))) .Element("Departments") .Elements("Department") .Elements("Item") .Select(e => new Item { DepartmentName = ?, DepartmentNames = ?, Name = e.Attribute("Name").Value, Names = ? }).ToList(); |
我不确定如何从a)父元素b)加载Dictionary对象中加载属性。 LINQ甚至有可能吗?本质上,我正在尝试整理内存中的数据结构。
在这种情况下,您需要在嵌套循环中访问外部元素的属性,因此我发现Linq
1 2 3 4 5 6 7 8 9 10 11 | var doc = XDocument.Load(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"InputData.xml")); var query = from department in doc.Element("Departments").Elements("Department") from item in department.Elements("Item") select new Item { DepartmentName = department.Attribute("Name").Value, DepartmentNames = department.Attributes().Where(a => a.Name !="Name").ToDictionary(a => a.Name.LocalName, a => a.Value), Name = item.Attribute("Name").Value, Names = item.Attributes().Where(a => a.Name !="Name").ToDictionary(a => a.Name.LocalName, a => a.Value), }; var items = query.ToList(); |
在这里,我假设您希望除
更新
如果您有待放入字典的已知属性列表,则可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 | var attributes = new HashSet<string>(new[] {"en-us","de-de","es-mx" }); // Possibly initialized in a static constructor. var query = from department in doc.Element("Departments").Elements("Department") from item in department.Elements("Item") select new Item { DepartmentName = department.Attribute("Name").Value, DepartmentNames = department.Attributes().Where(a => attributes.Contains(a.Name.LocalName)).ToDictionary(a => a.Name.LocalName, a => a.Value), Name = item.Attribute("Name").Value, Names = item.Attributes().Where(a => attributes.Contains(a.Name.LocalName)).ToDictionary(a => a.Name.LocalName, a => a.Value), }; var items = query.ToList(); |
我认为下面的代码是您想要的。我在这里进行了测试,它确实有效,但是我不确定这是否是您的意图。
我只是用所有语言值填充字典。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | var items = XDocument.Parse( File.ReadAllText( Path.Combine( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "InputData.xml"))) .Element("Departments") .Elements("Department") .Select( d => d.Elements("Item").Select(e => new Item { DepartmentName = d.Attribute("Name").Value, DepartmentNames = new Dictionary<string,string>() { {"en-us", d.Attribute("en-us").Value }, {"de-de", d.Attribute("de-de").Value} }, Name = e.Attribute("Name").Value, Names = new Dictionary<string,string>() { {"en-us", e.Attribute("en-us").Value}, {"de-de", e.Attribute("de-de").Value} } })).ToList(); |