2012-05-18 29 views
0

我有一個XML結構是這樣的:挑戰:LINQ到轉換層次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> 

我嘗試使用下面的代碼隱蔽這個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(); 
    } 
} 

然而,每個子類別的Parent屬性都會顯示「根類別」。相反,「cat 1.1」的Parent屬性應該說「cat1」。

我在這裏錯過了什麼?

回答

2

GetSubCategories,你讓每一個孩子的父當前對象的父:

select new CategoryXml 
{ 
    ... 
    Parent = parentCategory, 
    ... 
} 

我想你的意思是:

select new CategoryXml 
{ 
    ... 
    Parent = this, 
    ... 
} 

畢竟,每個孩子的家長是創造孩子的對象,對吧?

我會建議然而,你居然打電話給你select子句中的構造,就像這樣:

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); 
} 
+0

喬恩,感謝您的回答。然而,當我嘗試你的代碼時,我得到了每個父母的空值。 – notlkk

+0

明白了。只需添加Parent = parent;就是這樣。我愛你的解決方案。簡單而優雅。謝謝。 – notlkk

+0

@notlkk:哎呀,是的,修好了。 –