Reputation: 1231
I have an XML structure like this:
<?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>
I try to use the following code to covert this XML to objects:
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();
}
}
However, the Parent property for every sub category says "Root Category." Instead, the Parent property for "cat 1.1" should say "cat1."
What am I missing here?
Upvotes: 0
Views: 237
Reputation: 1500825
In GetSubCategories
, you're making the parent of every child the current object's parent:
select new CategoryXml
{
...
Parent = parentCategory,
...
}
I think you meant:
select new CategoryXml
{
...
Parent = this,
...
}
After all, the parent of each child is the object creating the child, right?
I would suggest, however, that you actually call the constructor within your select
clause, like this:
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);
}
Upvotes: 2