简体   繁体   English

c#将路径列表转换为xml的有效方法

[英]c# efficient way to convert a list of paths to xml

I have a list of folder paths coming from a database that I need to export to xml.我有一个来自数据库的文件夹路径列表,我需要将其导出到 xml。 The raw data looks as follows:原始数据如下所示:

在此处输入图片说明

What I need to do is create a tree like structure, similar to this within the xml:我需要做的是创建一个树状结构,类似于 xml 中的这个:

 - networkAdd
    - users
        - test1
           - delete unicode character test
                 - character test 1
                        - linked to folder
                 - character test 2
                 - character test 3
 - sp2013 
    - newTestsite
        - newTestLib
           - sampleFolder
           - Renamed at source again
           - SecurityTest2013Folder
        - Shared Documents
           - sample.folder

I have current got an efficient xml write method available to me BUT it requires a treeview.我目前有一个有效的 xml 写入方法可供我使用,但它需要一个树视图。 I took the list above (coming from the database) and converted it to a treeview that could be used with this method (which works fine) but it requires me to convert to a treeview first which is inefficient.我将上面的列表(来自数据库)转换为可以与此方法一起使用的树视图(工作正常),但它要求我首先转换为树视图,这是低效的。 I use this code:我使用这个代码:

public static TreeView PopulateTreeView(IEnumerable<FolderInfo> paths)
{
    var treeView = new TreeView();
    treeView.PathSeparator = "\\";

    TreeNode lastNode = null;
    string subPathAgg;
    string lastRootFolder = null;

    foreach (var item in paths)
    {
        var path = item.FolderName; // folder path.

        if (lastRootFolder != item.FolderRoot)
        {
            lastRootFolder = item.FolderRoot;
            lastNode = null;
        }

        subPathAgg = string.Empty;
        foreach (string subPath in path.Split('\\'))
        {
            if (subPath.Length > 0)
            {
                subPathAgg += subPath + "\\";
                TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);

                var newNode = new TreeNode
                {
                    Name = subPathAgg,
                    Text = subPath,
                    ImageIndex = 2,
                    ToolTipText = item.FullFolderPath
                };

                if (nodes.Length == 0)
                {
                    if (lastNode == null)
                        treeView.Nodes.Add(newNode);
                    else
                        lastNode.Nodes.Add(newNode);

                    lastNode = newNode;
                }
                else
                    lastNode = nodes[0];
            }
        }
    }

    return treeView;
}

This line of code becomes very slow to execute when I have over 10 million records to process: TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);当我有超过 1000 万条记录要处理时,这行代码的执行速度变得非常慢: TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);

It would be much more efficient for me to convert straight from DB to XML (without the treeview middle man).对我来说,直接从 DB 转换为 XML(没有树视图中间人)会更有效率。

Has anyone any advice on an alternative way of parsing folder paths into xml, taking nesting into consideration?考虑到嵌套,有人对将文件夹路径解析为 xml 的替代方法有什么建议吗? Thanks for any pointers in advance!提前感谢您的任何指点!

Turns out, if you can ensure that your strings are properly sorted (which should be easy if they're coming from a DB), this is pretty easy if you work directly with an XmlWriter .事实证明,如果您可以确保您的字符串正确排序(如果它们来自数据库,这应该很容易),如果您直接使用XmlWriter ,这将非常容易。 Something like:就像是:

var strings = new[]
{
    @"\\networkAdd",
    @"\\networkAdd\users",
    @"\\networkAdd\users\test1\",
    @"\\networkAdd\users\test1\delete unicode character test",
    @"\\networkAdd\users\test1\delete unicode character test\character test 1",
    @"\\networkAdd\users\test1\delete unicode character test\character test 1\linked to folder",
    @"\\networkAdd\users\test1\delete unicode character test\character test 2",
    @"\\networkAdd\users\test1\delete unicode character test\character test 3",
    @"http:\\sp2013",
    @"http:\\sp2013\newTestsite",
    @"http:\\sp2013\newTestlib",
    @"http:\\sp2013\newTestlib\sampleFolder",
};
// Obviously, stream it out to a file rather than an in-memory string
using (var stringWriter = new StringWriter())
using (var writer = new XmlTextWriter(stringWriter))
{
    writer.WriteStartDocument();
    writer.WriteStartElement("Items");

    var previous = Array.Empty<string>();
    foreach (var str in strings)
    {
        var current = str.Split('\\', StringSplitOptions.RemoveEmptyEntries);
        int i;
        // Find where the first difference from the previous element is
        for (i = 0; i < Math.Min(current.Length, previous.Length); i++)
        {
            if (current[i] != previous[i])
            {
                break;
            }
        }
        // i now contains the index of the first difference
        // First, close off anything in previous which isn't in the current
        for (int j = i; j < previous.Length; j++)
        {
            writer.WriteEndElement();
        }
        // Then, any new elements
        for (int j = i; j < current.Length; j++)
        {
            writer.WriteStartElement("Item");
            writer.WriteAttributeString("value", current[j]);
        }

        previous = current;
    }

    writer.WriteEndDocument();
}

Gives:给出:

<?xml version="1.0" encoding="utf-16"?>
<Items>
    <Item value="networkAdd">
        <Item value="users">
            <Item value="test1">
                <Item value="delete unicode character test">
                    <Item value="character test 1">
                        <Item value="linked to folder" />
                    </Item>
                    <Item value="character test 2" />
                    <Item value="character test 3" />
                </Item>
            </Item>
        </Item>
    </Item>
    <Item value="http:">
        <Item value="sp2013">
            <Item value="newTestsite" />
            <Item value="newTestlib">
                <Item value="sampleFolder" />
            </Item>
        </Item>
    </Item>
</Items>

It needs a bit of work around handling :// etc, but the basic principle should be sound.处理://等需要一些工作,但基本原则应该是合理的。

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

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