1

好的,所以我有一个自动生成的 xml 文件,它代表库中的某个文件夹结构:

<Folder>
    <Name>One</Name>
    <OutlineLevel>0</OutlineLevel>
</Folder>
<Folder>
    <Name>Two</Name>
    <OutlineLevel>1</OutlineLevel>
</Folder>
<Folder>
    <Name>Three</Name>
    <OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
    <Name>Four</Name>
    <OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
    <Name>Five</Name>
    <OutlineLevel>2</OutlineLevel>
</Folder>
<Folder>
    <Name>Six</Name>
    <OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
    <Name>Seven</Name>
    <OutlineLevel>3</OutlineLevel>
</Folder>
<Folder>
    <Name>Eight</Name>
    <OutlineLevel>1</OutlineLevel>
</Folder>

但是,我需要它在以下结构中看起来更人性化且不那么尴尬:

<Folder Name="One">
    <Folder Name="Two">
        <Folder Name="Three">
            <Folder Name="Four"></Folder>
        </Folder>
        <Folder Name="Five">
            <Folder Name="Six"></Folder>
            <Folder Name="Seven"></Folder>
        </Folder>
    </Folder>
    <Folder Name="Eight"></Folder>
</Folder>

我已经研究了很长时间了,我对如何将它包装成一个方法缺乏任何想法。任何建议将不胜感激。

到目前为止,我已经成功地将它放入我的类的对象中,如下所示:

class MyFolder
{
    private List<MyFolder> _folders;
    public List<MyFolder> Folders
    {
        get
        {   if (_folders == null)
            { _folders = new List<MyFolder>(); }
            return _folders;  }
        set { _folders = value; }
    }
    public string Name { get; set; }
}

老实说,不知道这是否会引导我到任何地方,我现在有一个 MyFolder,其中有 MyFolders 和其他 MyFolders 等,希望这是有道理的。

4

1 回答 1

1

我制作了一个控制台应用程序。它产生你需要的东西。我已将您的 XML 包装到 FolderTree 元素中,只是为了便于解析。

static void Main(string[] args)
{
    var xml = @"<FolderTree>
        <Folder>
            <Name>One</Name>
            <OutlineLevel>0</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Two</Name>
            <OutlineLevel>1</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Three</Name>
            <OutlineLevel>2</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Four</Name>
            <OutlineLevel>3</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Five</Name>
            <OutlineLevel>2</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Six</Name>
            <OutlineLevel>3</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Seven</Name>
            <OutlineLevel>3</OutlineLevel>
        </Folder>
        <Folder>
            <Name>Eight</Name>
            <OutlineLevel>1</OutlineLevel>
        </Folder>
        </FolderTree>
    ";

    var root = XElement.Parse(xml);
    var elements = root.Elements().ToList();
    var rootFolderString = GetItemsAtLevel(new Queue<XElement>(elements), 0).First().ToString();
}

private static void TransformElement(XElement folder)
{
    folder.Element("OutlineLevel").Remove();
    var nameElement = folder.Element("Name");
    nameElement.Remove();
    folder.Add(new XAttribute(nameElement.Name, nameElement.Value));
}

private static IEnumerable<XElement> GetItemsAtLevel(Queue<XElement> elements, int level)
{
    while (elements.Any())
    {
        var parent = elements.Dequeue();
        var children = new Queue<XElement>();
        while (elements.Any() && (int)elements.Peek().Element("OutlineLevel") > level)
        {
            children.Enqueue(elements.Dequeue());
        }

        if (children.Any())
        {
            var subtree = GetItemsAtLevel(children, level + 1);
            parent.Add(subtree);
        }

        TransformElement(parent);
        yield return parent;
    }
}
于 2013-01-23T11:40:20.397 回答