
Introduction
In this article, I will show you how to use a recursive function to read a directory structure and then save it to XML, but first of all let me tell you the purpose of this application. I had to develop a desktop application in Flash, and it had to open audio files from the PC. I know that Flash can't execute OpenFileDialogBox
and get the file path, ...but it can read XML files! So, I decided to create a default directory ("Media Library") where the user could organize the audio files in the way he wants.
But, how will the Flash know what the directory has??? From Flash I call my dirSinc.exe (.NET app.) that reads the complete "Media Library" directory structure and saves it to dirSinc.XML. In the Flash application there is a FlashTreeView
(FTree component) that shows in a TreeView
the content of "Media Library" and from where the user can select and open a file.
I think this introduction is enough to understand what we are gonna do...so let's go to the code!!
Using the code
I decided to do a generic example application for this article, so the form has a FolderBrowserDialog
to select the folder you want to work with. When you try it, don't select the "C:\windows" directory...because it will generate an immense XML!! ;)

First of all, we have to declare the object that will manipulate the XML document. It has to be class level because it will be used by more than one function:
Public Class frmXML Inherits System.Windows.Forms.Form
Dim xmlDoc As New XmlDocument
btnSinc_Click event
Considering you already know how to create an XML document with its elements and attributes, let's focus on the createRootNode()
call.
Private Sub btnSinc_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles
btnSinc.Click
If txtPath.Text = "" Then
Exit Sub
End If
Try
xmlDoc.RemoveAll()
lblStatus.Text = "Readind directory structure..."
xmlDoc.AppendChild(xmlDoc.CreateProcessingInstruction(_
"xml", "version='1.0'"))
createRootNode()
xmlDoc.Save("structure_of_" & _
txtPath.Text.Substring(txtPath.Text.LastIndexOf("\") + 1) & _
".xml")
lblStatus.Text = "The XML document was created."
Catch ex As Exception
MessageBox.Show(ex.ToString)
End Try
End Sub
createRootNode()
The XML format I adopted for this example has a "myRoot
" node with its label and description. (This is what this Sub creates.) From here we will create the "folder
" and "files
" nodes with their label
, description
, filePath
, and size
attributes. Since "myRoot
" node was appended, we call the loopNodes()
function sending the oElmntRoot
: "myRoot
" node (user selected folder), txtPath.Text
: the full path to the user selected folder.
loopNodes()
Finally, we are at the recursive function. Here we have two 'For Each
' loops, one for folders and the other for files. We first start with the folders loop that will call itself as many times as the number of folders in order to find out if a folder has subfolders (child nodes) inside.
ofs.GetDirectories
will let us loop through all the subfolders in the current folder, if true we create the XML element with its attributes, and then make the recursive call until there are no subfolders in the current folder. There begins the 'files' loop creating the corresponding XML element. But this 'file' loop doesn't make a recursive call because a file does not have subfiles. :)
Private Function loopNodes(ByVal oElmntParent As XmlElement, _
ByVal strPath As String)
Dim d As DirectoryInfo
Dim ofs As New DirectoryInfo(strPath & "\")
'Folders Loop -------------------------------------------------
'Gets the directories of the current node.
'It changes for each recursive call
For Each d In ofs.GetDirectories
'Manipulates the sub folders nodes
Dim oElmntChild As XmlElement
oElmntChild = xmlDoc.CreateElement("folder")
oElmntChild.SetAttribute("label", d.Name)
'Adds the "folder" node
oElmntParent.AppendChild(oElmntChild)
'Recursive call
loopNodes(oElmntChild, strPath & "\" & d.Name)
Next
'Files Loop ------------------------------------------------------
Dim oFile As FileInfo
For Each oFile In ofs.GetFiles
Dim oElmntLeaf As XmlElement 'Manipulates the files nodes
oElmntLeaf = xmlDoc.CreateElement("file")
oElmntLeaf.SetAttribute("label", oFile.Name)
oElmntLeaf.SetAttribute("filePath", strPath)
oElmntLeaf.SetAttribute("bytesSize", CType(oFile.Length, String))
oElmntParent.AppendChild(oElmntLeaf) 'Adds the "file" node
Next
End Function
The key point to understand in the recursive function is that when it calls itself it creates new instances of the objects inside, and when it finishes, returns to the point from where it was called. May be the first time you'll need to debug the function step by step to understand what is happening in each loop.
Tip: This function could be used to fill a TreeView
, provided the structure is not very big. In that case it maybe better to fill the folders while you open each one.
Hope this article helps you!