Using the File System Object (FSO) we can traverse through our website’s contents and write them out in a nicely nested form in an XML file. We could then use that file in a content management system or a TreeView control for example.

The variables

First we declare our variables:

<%@Language="VBScript"%>
<%Option Explicit%>
<%Response.Buffer = True%>
<%
'-- set a 600 second timeout value in case it hangs
Server.ScriptTimeOut = 600
On Error Resume Next

Dim strRootFolder
Dim intLenRootFolder
Dim objFSO
Dim strXmlFile
Dim strVbCrLf
Dim strVbTab
Dim numTree
Dim objFile
...

Then we set them equal to some values:

...
strVbCrLf = VbCrLf
strVbTab = VbTab
numTree = 0
strRootFolder = Request.ServerVariables("APPL_PHYSICAL_PATH")
intLenRootFolder = Len(strRootFolder)
strXmlFile = "<root type=""root"" value=""Site Root"" url=""/"">" & strVbCrLf
...

The strXmlFile is the root node of our XML file and we can set it equal to whatever we want as long as the type is equal to root.

Creating and writing to the XML file


...
'-- create an instance of the FSO object
Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
'-- open file for writing, create if not there, and open as text
Set objFile = objFSO.CreateTextFile(strRootFolder & "menuitems.xml", True, False)
'-- write root node
objFile.Write(strXmlFile)
...

You can change the location of this file by adding folders in the Windows format. For example, to put it in a folder called navigation, change the location like so:
Set objFile = objFSO.CreateTextFile(strRootFolder & “navigation\menuitems.xml“, True, False)

Traversing through the site

...
Call TraverseSite(strRootFolder,numTree)

Sub TraverseSite(strFolder,thisTree)
...

We create a sub called TraverseSite, which is responsible for going through the folders of the site and creating nodes in our XML file.  It accepts two parameters:

  1. strRootFolder : the specific folder we are in
  2. numTree: how many levels deep we are in the website folder structure

When we first call it, we pass the root folder to it, and 0 for the folder level. This sub gets called within itself as it goes deeper through the folders and the parameters change accordingly.

The basic logic for this sub is:

Take a folder
Show name of folder without closing xml tag
If there are subfolders Then
   For each subfolder
      Run same procedure with new folder and level
   Next
End If
If there are subfiles Then
   Show subfiles with closing xml tag
End If
Add closing xml tag

So, first we traverse through the folders:

...
	 '-- reset the string which gets written to the XML file
	strXmlFile = ""
	'-- declare our variables in the sub
	Dim objFolder, objSubFolder, objSubFile, i
	Dim objThisFolder, objthisFile, strURL, strFolderURL

	'-- grab the folder passed in the sub
	Set objFolder = objFSO.GetFolder(strFolder)
	'-- grab its subfolders
	Set objSubFolder = objFolder.SubFolders
	'-- grab its files
	Set objSubFile = objFolder.Files

	'-- properly nest the nodes for a nice display
	For i = 1 To thisTree
		strXmlFile = strXmlFile & strVbTab
	Next
	'-- get the folder path excluding the application root folder
	strFolderURL = Mid(objFolder.Path, intLenRootFolder, Len(objFolder.Path))
	'-- turn the physical path into a relative path
	strFolderURL = Replace(strFolderURL, "\", "/")
	'-- append node to the output unless it is the root folder
	If thisTree > 0 Then
		strXmlFile = strXmlFile & "<folder type=""folder"" value=""" & objFolder.Name & """
url=""" & strFolderURL & "/"">" & strVbCrLf
		objFile.Write(strXmlFile)
	End If
	'-- reset the string output again
	strXmlFile = ""
	'-- if there are subfolders under it then run sub again for each one
	If Not IsEmpty(objSubFolder) Then
		For Each objThisFolder in objSubFolder
			Call TraverseSite(objThisFolder.Path,thisTree + 1)
		Next
	End If
...

Then we loop through the file contents of each folder we are in:

...
	'-- if there are files in the folder
	If Not IsEmpty(objSubFile) Then
		For Each objthisFile in objSubFile
			'-- properly nest the nodes for a nice display
			For i = 0 To thisTree + 1
				strXmlFile = strXmlFile & strVbTab
			Next
			'-- get the virtual path
			strURL = Mid(objthisFile.Path, intLenRootFolder, Len(objthisFile.Path))
			strURL = Replace(strURL, "\", "/")
			'-- create output string
			strXmlFile = strXmlFile & "<document type=""document"" value=""" & objthisFile.Name
& """ url=""" & strURL & """/>" & strVbCrLf
		Next
		'-- write output to XML file
		objFile.Write(strXmlFile)
		strXmlFile = ""
	End If
	For i = 1 To thisTree
		strXmlFile = strXmlFile & strVbTab
	Next
	'-- close the folder node
	If thisTree > 0 Then
		strXmlFile = strXmlFile & "</folder>" & strVbCrLf
	End If
	objFile.Write(strXmlFile)
	strXmlFile = ""
	'-- show the progress of the code as it goes through folders
	Response.Write("Folder <font color=""#FF0000"">" & strFolderURL & "</font> written!<br>")
	Response.Flush
End Sub

'--write end root node
objFile.Write("</root>")
objFile.close
Set objFile = Nothing
Set objFSO = Nothing
%>

XML file created

The resulting XML file, menuitems.xml, should look something like this:

Menu Items

Including other properties in the XML file

The name and path of a folder/file may be the basic output here, but we can easily expand them to include other properties as well. For example, using FSO we can also output the size, date created, date last modified, etc. To add for example the date last modified of files to the XML file output, change the strXmlFile output above (in the file output section) like so:

...
strXmlFile = strXmlFile & "<document type=""document"" value=""" & objthisFile.Name
& """ url=""" & strURL & """" & " datelastmodified=""" & objthisFile.DateLastModified & """/>" & strVbCrLf
...

And the expanded XML file output would then look like this:

Expanded Menu Items

We can of course go beyond the FSO object for outputing properties in the XML file. We could for example, instantiate a component that reads image properties if the file we are on happens to be an image, and include those properties as well in the output – like image width, height etc.

2 Responses to Generating an XML file of your website’s folders/files

  • Adders Ladders

    Hi Evagoras,
    Thanks very much for sharing. This actually came up at 2nd from top of the page when I searched Google for ‘writing directory contents to and xml file’ – well done!
    Basically I have limited knowledge of ASP but wanted to find a script or program so that I could write the contents of a specific directory, C:\directory1, for example to an xml file. All I need in the output file is the file name and extension.
    Can your code be modified please to make this happen and so that it does not reference a website directory?
    Thanks very much for your help.
    Ad

    • Evagoras Charalambous

      Thanks, I am glad to be of help.

      What you want should be pretty easy to do. In the downloaded source code of this post, you should see lines 71-82:

      For Each objthisFile in objSubFile
      ...
      Next

      This chunk is responsible for looping through every file in the directory and writing out a line for each one in your XML file. Lines 80-81 (the one starting with strXmlFile = …) are the ones handling what you see for each line. Change those to whatever you want to add/remove/edit node properties. If you want to have the same output structure, but just want the URL changed to show just the file name, you could change just line 81 like this:

      & objthisFile.Name & """ url=""" & objthisFile.Name & """/>" & strVbCrLf