I'm currently trying to render a tree of Flickr Collections and Sets as HTML from C#. I'm using the Flickr.NET library to a list of all my collections with their childcollections and sets.
What I need to do is to render this tree as a HTML tree using nested unordered lists and I'm thinking of a recursive solution since a Collection can hold one or more sets and also hold child collections which again can hold sets and collections.
What I have right now is a list of all the root collections, their childcollections and their sets. So i.e. my Flickr tree looks like this:
Collection (this collection is in my list as an object itself)
Collection
Collection
Collection (this collection is in my list as an object itself)
Collection
Collection
And basically it could looks a hundred more ways since editors will eventually create a number more Collections within collections and sets within sets.
So, for every collection and set, I need a new nested unordered list.
I know this is quite complex, but nonetheless, it would be great to have an algorithm to render the tree as HTML. I've just become a tad too rusty when it comes to recursive algorithms :-/
I guess my basecase here is if the current collection doesn't have any childcollections and doesn't have any, then I can stop the recursive method?
Any help/hint on this is greatly appreciated!
Thanks a lot in advance.
All the best,
Bo
SOLUTION
I broke down the algorithms in four steps:
private void LoadFlickrTreeRecursive()
{
foreach (var collection in allCollections)
{
flickrTreeMarkup.Append("<ul class='collection'>");
flickrTreeMarkup.Append("<li>" + collection.Title + "</li>");
if (collection.Sets.Count > 0)
RenderFlickPhotoSet(collection.Sets);
if (collection.Collections.Count > 0)
RenderFlickrCollectionRecursive(collection.Collections);
flickrTreeMarkup.Append("</ul>");
}
}
private void RenderFlickPhotoSet(System.Collections.ObjectModel.Collection<CollectionSet> sets)
{
foreach (var set in sets)
{
flickrTreeMarkup.Append("<ul class='set'>");
flickrTreeMarkup.Append("<li>" + set.Title + "</li>");
var photos = flickr.PhotosetsGetPhotos(set.SetId);
if (photos.Count > 0)
{
flickrTreeMarkup.Append("<ul class='photos'>");
foreach (var photo in photos)
{
flickrTreeMarkup.Append("<li>" + photo.Title + "</li>");
}
flickrTreeMarkup.Append("</ul>");
}
flickrTreeMarkup.Append("</ul>");
}
}
private void RenderFlickrCollectionRecursive(System.Collections.ObjectModel.Collection<Collection> collections)
{
foreach (var collection in collections)
{
flickrTreeMarkup.Append("<ul class='collection'>");
flickrTreeMarkup.Append("<li>" + collection.Title + "</li>");
RenderFlickPhotoSet(collection.Sets);
if (collection.Collections.Count > 0)
{
RenderFlickrCollectionRecursive(collection.Collections);
}
flickrTreeMarkup.Append("</ul>");
}
}
Works like a charm :-)
However, if anyone know of a better way than this, please let me know. Thanks!
This algorithm should work with a TreeView control:
function rec(Collection c, TreeNode n)
{
TreeNode me = new TreeNode();
n.ChildNodes.Add(me);
for each collection v in c:
rec(v, me)
for each set s in c:
AddSet(s, me)
}