简体   繁体   English

将笨拙的xml文档结构转换为友好的结构

[英]Converting an awkward xml document structure into a friendly one

Okay, so I have an auto-generated xml file which represents a certain folder structure in a library: 好的,所以我有一个自动生成的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>

However, I need it to look more human-friendly and less awkward in a following structure: 但是,我需要它在以下结构中看起来更人性化且不尴尬:

<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>

I have been looking at it for quite a while already and I am lacking any ideas as to how to wrap it into a method. 我已经看了很长时间了,而且我对如何将其包装到方法中一无所知。 Any suggestions would be highly appreciated. 任何建议将不胜感激。

So far I have been successfull with putting it into objects of my class, which looks like this: 到目前为止,我已经成功地将其放入类的对象中,如下所示:

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; }
}

Don't know if this leads me anywhere to be honest, I now have a MyFolder which has MyFolders which have other MyFolders etc, hopefully this makes sense. 不知道这是否使我无话可说,我现在有一个MyFolder,其中有MyFolders和其他MyFolders等,希望这是有道理的。

I've made a console app. 我做了一个控制台应用程序。 It yields what you need. 它产生您所需要的。 I have wrapped your XML into the FolderTree element just to make parsing easy. 我将您的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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM