0

次のような 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」となるはずです。

ここで何が欠けていますか?

4

1 に答える 1

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);
}
于 2012-05-19T00:00:46.777 に答える