繁体   English   中英

在C#中使用LINQ解析XML

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM