A few months ago I was given a project to maintain a corporate website. This website was previously hosted in a CMS in remote site. When I received the CD containing the project files, it was already in ‘offline’ website format. It means all files are now static HTML. I suspect that it generated using those website downloaders (Offline Explorer, etc.).
The problem with static HTML website is there are many duplicates of information. One news article will show up as many files that located in different folders. It could be under News folder, News Archive folder, Tags folder, etc.
It means my task will become a boring headache, since I will need to add content, add it to the respective folders, and manually update all the linkage regularly.
So I came out with a simple program to help me generating the content, upload the attachment and to update the linkage. This is when I hit the problem. Because most of the time, a news article will contain attachments. The attachments will be stored under Attachments folder, but the pages that linked to that attachment are scattered all over the place. I also need to update the ‘index’ files of each category (Archive by Year, Archive by Tag, Archive by Category, etc.)
Instead of reinventing the wheel, I asked Google to find me the wheel 😀 David M. Howard has solved this problem 9 years ago 🙂 Thank You David!
His solution was written in Java, I just need to convert it to .NET and tweaked it a little without any difficulties.
The output of the test program are as follows:
'Filename: MyPath.vb Imports System.IO Imports System.Collections Public Class MyPath Public Shared Function getRelativePath(ByVal home As String, ByVal remote As String) As String Return getRelativePath(New FileInfo(home), New FileInfo(remote)) End Function Public Shared Function getRelativepath(ByVal home As String, ByRef remote As FileInfo) As String Return getRelativepath(New FileInfo(home), remote) End Function Public Shared Function getRelativePath(ByRef home As FileInfo, ByVal remote As String) As String Return getRelativePath(home, New FileInfo(remote)) End Function Public Shared Function getRelativePath(ByRef home As FileInfo, ByRef remote As FileInfo) As String Dim homepathList As New ArrayList Dim remotePathList As New ArrayList Dim result As String = "" If ((home.Exists And remote.Exists) Or home.Directory.Exists Or remote.Directory.Exists) Then 'initialize the paths initPathList(home.Directory, homepathList) If remote.Attributes = FileAttributes.Directory Then initPathList(remote.Directory, remotePathList) Else initPathList(remote, remotePathList) End If Dim ihome As Integer = homepathList.Count - 1 Dim iremote As Integer = remotePathList.Count - 1 'Do we have common parent If Not homepathList(ihome).Equals(remotePathList(iremote)) Then Return remote.FullName End If 'remove common parent While (ihome >= 0 And iremote >= 0) If homepathList(ihome).Equals(remotePathList(iremote)) Then ihome -= 1 iremote -= 1 Else Exit While End If End While 'Add relative path While ihome >= 0 result &= ".." & System.IO.Path.DirectorySeparatorChar.ToString() ihome -= 1 End While 'Combine relative path result with the remote While iremote > 0 result &= remotePathList(iremote).ToString() & System.IO.Path.DirectorySeparatorChar.ToString() iremote -= 1 End While result &= remotePathList(iremote).ToString() Else If Not home.Exists Then Throw New Exception(home.FullName & " is not exist!") End If If Not remote.Exists Then Throw New Exception(remote.FullName & " is not exist!") End If End If Return result End Function Public Shared Sub initPathList(ByRef f As FileInfo, ByRef ar As ArrayList) ar.Add(f.Name) initPathList(f.Directory, ar) End Sub Public Shared Sub initPathList(ByRef dir As DirectoryInfo, ByRef ar As ArrayList) ar.Add(dir.Name) While Not dir.Parent Is Nothing dir = dir.Parent ar.Add(dir.Name) End While End Sub End Class
'Filename: testMyPath.vb Imports System.IO Module Module1 Sub Main() While True Console.Write("Home: ") Dim homePath As String = Console.ReadLine() Console.Write("Remote: ") Dim remotePath As String = Console.ReadLine() Try Console.WriteLine("Relative Path: " & MyIO.MyPath.getRelativePath(homePath, remotePath)) Catch ex As Exception Console.WriteLine("ERROR: " & ex.ToString()) End Try Console.WriteLine() End While End Sub End Module