Как заполнить XML-дерево из файловой системы
Распространенным и полезным применением XML-деревьев является использование их в качестве иерархической структуры для хранения данных с именем и значением. Можно заполнить дерево XML-данными, распределенными внутри иерархии, после чего выполнять по нему запросы, преобразования и, если необходимо, сериализацию. В следующем сценарии многие виды семантических конструкций, присущих XML, например пространства имен и обработка пробельных символов, неважны. Вместо этого XML-дерево используется как небольшая иерархическая база данных для одного пользователя, которая находится в памяти.
Пример
В следующем примере происходит заполнение XML-дерева из локальной файловой системы при помощи рекурсии. Затем выполняется запрос по дереву и вычисляется общий размер всех файлов в дереве.
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
Этот пример выводит данные примерно так:
<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