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

c# efficient way to convert a list of paths to xml

我有一个来自数据库的文件夹路径列表,我需要将其导出到 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

我目前有一个有效的 xml 写入方法可供我使用,但它需要一个树视图。我获取了上面的列表(来自数据库)并将其转换为可以与此方法一起使用的树视图(效果很好)但它需要我先转换为效率低下的树视图。我使用此代码:

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

当我有超过 1000 万条记录要处理时,这行代码执行起来非常慢: TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);

直接从 DB 转换为 XML(没有 treeview 中间人)对我来说会更有效率。

有没有人对将文件夹路径解析为 xml 并考虑嵌套的替代方法有任何建议?提前感谢您的指点!

事实证明,如果您可以确保您的字符串正确排序(如果它们来自数据库,这应该很容易),如果您直接使用 XmlWriter,这将非常容易。类似于:

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

给出:

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

在处理 :// 等方面需要做一些工作,但基本原则应该是合理的。