mstfcck mstfcck - 1 month ago 13
C# Question

Convert to html (nested ul li) from list in C#

I have a list like the following (sample):

Convert to html (nested ul li) from list in C#

But this list is just a sample for logic. The list should be dynamic. List field may have more than 3 and The list can have a collection of the child (data format like json)

I want to convert nested ul-li html tags. I think, I can do that with reflection like following. But I am using to the reflection first time. My code is like following for now. What should I do for that?

public static string ConvertToHtml<T>(IEnumerable<T> list) where T : class
{
StringBuilder html = new StringBuilder();
foreach (var item in list)
{
Type itemType = item.GetType();
if (itemType.IsClass)
{
FieldInfo[] fieldInfo = itemType.GetFields(BindingFlags.Public | BindingFlags.Instance); // Field?
if (fieldInfo.Any())
{
foreach (var field in fieldInfo)
{
var name = field.Name;
var value = field.GetValue(item);
}
}
PropertyInfo[] propertyInfo = itemType.GetProperties(BindingFlags.Public | BindingFlags.Instance); // Property?
if (propertyInfo.Any())
{
foreach (var property in propertyInfo)
{
var name = property.Name;
var value = property.GetValue(item);
}
}

}
}
return string.Empty;
}

Answer

Most likely you have chosen a wrong approach to do the task. The reflection is typically used for querying the runtime code structures like types, their fields, properties and methods. The most common use case for that is creating a method for serialization/deserialization of arbitrary types.

In your case it does not look like the arbitrary structure - you have quite strict data structure even though it is supports infinite (conceptually) nested levels (like JSON). In other words, you have "tree" https://en.wikipedia.org/wiki/Tree_(data_structure).

To traverse it several algorithms exists: https://en.wikipedia.org/wiki/Tree_traversal and of course for most of them you can easy find the sample implementation: Implementing Depth First Search into C# using List and Stack But the problem is a bit tricky than you can expect as you first need to understand the concept.

The tree traversal algorithms are typically recursive. So in order to do it right you have to get into this concept as well.

After that the code for building the list is quite simple:

public class Node {
    string Name { get; set; }
    IList<Node> Subnodes { get; private set; }
}

private void BuildList(Node node, StringBuilder sb) {
    sb.Append("<ul>");
    foreach (var n in node.Subnodes) {
        sb.Append("<li>" + n.Name);
        BuildList(n, sb);
        sb.Append("</li>");
    }
    sb.Append("</ul>");
}

public string BiuldList(Node root) {
    var sb = new StringBuilder();
    BuildList(root, sb);
    return sb.ToString();
}

EDIT

Using the given code it would generate empty <ul></ul> tags inside the <li></li> items who don't have children. So I did a slightly change adding a condition to only create the sub list when there are children.

Code:

private void BuildList(Node node, StringBuilder sb) {
       if(node.Subnodes.Count > 0){
            sb.Append("<ul>");
            foreach (var n in node.Subnodes) {
                sb.Append("<li>" + n.Name);
                BuildList(n, sb);
                sb.Append("</li>");
            }
            sb.Append("</ul>");
        }
    }