我有一个文件夹路径列表,该文件夹路径来自我需要导出到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;
}
当我要处理超过一千万条记录时,这行代码执行起来会非常缓慢:TreeNode[] nodes = treeView.Nodes.Find(subPathAgg, true);
对我来说,直接从DB转换为XML(没有树视图中间人)会更有效率。
有人考虑将嵌套的路径解析为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>
需要处理://
等方面的一些工作,但基本原理应该是正确的。