How to: Populate an XML Tree from the File System
A common and useful application of XML trees is as a hierarchical name/value data store. You can populate an XML tree with hierarchical data, and then query it, transform it, and if necessary, serialize it. In this usage scenario, many of the XML specific semantics, such as namespaces and white space behavior, are not important. Instead, you are using the XML tree as a small, in memory, single user hierarchical database.
Example
The following example populates an XML tree from the local file system using recursion. It then queries the tree, calculating the total of the sizes of all files in the tree.
class Program
{
static XElement CreateFileSystemXmlTree(string source)
{
DirectoryInfo di = new DirectoryInfo(source);
return new XElement("Dir",
new XAttribute("Name", di.Name),
from d in Directory.GetDirectories(source)
select CreateFileSystemXmlTree(d),
from fi in di.GetFiles()
select new XElement("File",
new XElement("Name", fi.Name),
new XElement("Length", fi.Length)
)
);
}
static void Main(string[] args)
{
XElement fileSystemTree = CreateFileSystemXmlTree("C:/Tmp");
Console.WriteLine(fileSystemTree);
Console.WriteLine("------");
long totalFileSize =
(from f in fileSystemTree.Descendants("File")
select (long)f.Element("Length")).Sum();
Console.WriteLine("Total File Size:{0}", totalFileSize);
}
}
Module Module1
Function CreateFileSystemXmlTree(ByVal source As String) As XElement
Dim di As DirectoryInfo = New DirectoryInfo(source)
Return <Dir Name=<%= di.Name %>>
<%= From d In Directory.GetDirectories(source) _
Select CreateFileSystemXmlTree(d) %>
<%= From fi In di.GetFiles() _
Select <File>
<Name><%= fi.Name %></Name>
<Length><%= fi.Length %></Length>
</File> %>
</Dir>
End Function
Sub Main()
Dim fileSystemTree As XElement = CreateFileSystemXmlTree("C:/Tmp")
Console.WriteLine(fileSystemTree)
Console.WriteLine("------")
Dim totalFileSize As Long = _
( _
From f In fileSystemTree...<File> _
Select CLng(f.<Length>(0)) _
).Sum()
Console.WriteLine("Total File Size:{0}", totalFileSize)
End Sub
End Module
This example produces output similar to the following:
<Dir Name="Tmp">
<Dir Name="ConsoleApplication1">
<Dir Name="bin">
<Dir Name="Debug">
<File>
<Name>ConsoleApplication1.exe</Name>
<Length>4608</Length>
</File>
<File>
<Name>ConsoleApplication1.pdb</Name>
<Length>11776</Length>
</File>
<File>
<Name>ConsoleApplication1.vshost.exe</Name>
<Length>9568</Length>
</File>
<File>
<Name>ConsoleApplication1.vshost.exe.manifest</Name>
<Length>473</Length>
</File>
</Dir>
</Dir>
<Dir Name="obj">
<Dir Name="Debug">
<Dir Name="TempPE" />
<File>
<Name>ConsoleApplication1.csproj.FileListAbsolute.txt</Name>
<Length>322</Length>
</File>
<File>
<Name>ConsoleApplication1.exe</Name>
<Length>4608</Length>
</File>
<File>
<Name>ConsoleApplication1.pdb</Name>
<Length>11776</Length>
</File>
</Dir>
</Dir>
<Dir Name="Properties">
<File>
<Name>AssemblyInfo.cs</Name>
<Length>1454</Length>
</File>
</Dir>
<File>
<Name>ConsoleApplication1.csproj</Name>
<Length>2546</Length>
</File>
<File>
<Name>ConsoleApplication1.sln</Name>
<Length>937</Length>
</File>
<File>
<Name>ConsoleApplication1.suo</Name>
<Length>10752</Length>
</File>
<File>
<Name>Program.cs</Name>
<Length>269</Length>
</File>
</Dir>
</Dir>
------
Total File Size:59089