挑战:LINQ将层次结构XML转换为链接对象

挑战:LINQ将层次结构XML转换为链接对象,linq,linq-to-xml,Linq,Linq To Xml,我的XML结构如下所示: <?xml version="1.0" encoding="utf-8"?> <categories version="2.0"> <category> <name>cat1</name> <category> <name>cat 1.1</name> </category> <category>

我的XML结构如下所示:

<?xml version="1.0" encoding="utf-8"?>
<categories version="2.0">
  <category>
    <name>cat1</name>
    <category>
      <name>cat 1.1</name>
    </category>
    <category>
      <name>cat 1.2</name>
    </category>
  </category>
</categories>
private CategoryXml(XElement current, string name, int level, int order,
                    CategoryXml parent)
{
    Name = name;
    Level = level;
    Order = order;
    Parent = parent;
    Children = current.Elements("category")
                      .Select((child, index) => new CategoryXml(child,
                                 (string) child.Element("name"),
                                 Level + 1,
                                 index + 1,
                                 this))
                      .ToList();
}

public CategoryXml(XElement root)
{
    this(root, "Root Category", level: 0, order: 1, parent: null);
}

第一类
第1.1类
第1.2类
我尝试使用以下代码将此XML转换为对象:

XElement root = XDocument.Load(categoryXmlFile).Descendants("categories").First();
CategoryXml cat = new CategoryXml(root);

class CategoryXml
{
    public string Name { get; set; }
    public int Level { get; set; }
    public int Order { get; set; }
    public CategoryXml Parent { get; set; }
    public List<CategoryXml> Children { get; set; }

    CategoryXml() { }

    public CategoryXml(XElement root)
    {
        Name = "Root Category";
        Level = 0;
        Order = 1;
        Parent = null;
        Children = GetSubCategories(root, Level, this);
    }


    private List<CategoryXml> GetSubCategories(XElement parentElement, int level, CategoryXml parentCategory)
    {
        int order = 1;
        level++;

        var s = from childElement in parentElement.Elements("category")
                select new CategoryXml
                {
                    Name = childElement.Element("name").Value,
                    Level = level,
                    Order = order++,
                    Parent = parentCategory,
                    Children = GetSubCategories(childElement, level, this)
                };

        return s.ToList();
    }
} 
XElement root=XDocument.Load(categoryXmlFile).subscriptions(“categories”).First();
CategoryXml cat=新的CategoryXml(根);
类别xml
{
公共字符串名称{get;set;}
公共整数级别{get;set;}
公共整数顺序{get;set;}
公共类别XML父项{get;set;}
公共列表子项{get;set;}
CategoryXml(){}
公共类别XML(XElement根目录)
{
Name=“根类别”;
级别=0;
顺序=1;
Parent=null;
Children=GetSubCategories(根、级别、此);
}
私有列表GetSubCategories(XElement parentElement、int级别、CategoryXml parentCategory)
{
整数阶=1;
级别++;
var s=来自parentElement.Elements(“类别”)中的childElement
选择新类别XML
{
Name=childElement.Element(“Name”).Value,
级别=级别,
订单=订单+++,
父类=父类,
Children=GetSubCategories(childElement、level、this)
};
返回s.ToList();
}
} 
但是,每个子类别的父属性都是“根类别”。相反,“cat 1.1”的父属性应该是“cat1”


我在这里遗漏了什么?

GetSubCategories
中,您将每个子对象的父对象设置为当前对象的父对象:

select new CategoryXml
{
    ...
    Parent = parentCategory,
    ...
}
我想你的意思是:

select new CategoryXml
{
    ...
    Parent = this,
    ...
}
毕竟,每个子对象的父对象是创建子对象的对象,对吗

但是,我建议您在
select
子句中实际调用构造函数,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<categories version="2.0">
  <category>
    <name>cat1</name>
    <category>
      <name>cat 1.1</name>
    </category>
    <category>
      <name>cat 1.2</name>
    </category>
  </category>
</categories>
private CategoryXml(XElement current, string name, int level, int order,
                    CategoryXml parent)
{
    Name = name;
    Level = level;
    Order = order;
    Parent = parent;
    Children = current.Elements("category")
                      .Select((child, index) => new CategoryXml(child,
                                 (string) child.Element("name"),
                                 Level + 1,
                                 index + 1,
                                 this))
                      .ToList();
}

public CategoryXml(XElement root)
{
    this(root, "Root Category", level: 0, order: 1, parent: null);
}

乔恩,谢谢你的回答。然而,当我尝试你的代码时,我得到了每个家长的空值。明白了。只需添加父项=父项;就这样。我喜欢你的解决方案。朴素典雅。谢谢