[英]Parsing XML with LINQ in C#
我正在尝试使用LINQ在C#和XML之间进行映射。 当前,我有一个用C#定义的类,如下所示:
Item.cs
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
<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”)。 目前,我有以下内容:
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甚至有可能吗? 本质上,我试图在内存中整理数据结构。
在这种情况下,需要在嵌套循环中访问外部元素的属性,我发现from / select
语法中的Linq更加舒适。 从而:
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();
在这里,我假设您希望将字典中除Name
属性(其具有自己的属性)之外的每个属性都放置在字典中。
更新
如果您有待放入字典的已知属性列表,则可以执行以下操作:
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();
我认为下面的代码是您想要的。 我在这里进行了测试,它确实有效,但是我不确定这是否是您的意图。 我只是用所有语言值填充字典。
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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.