从 C# 中的列表转换为 html(嵌套 ul li)

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

我有如下列表(示例):

但此列表只是逻辑示例。该列表应该是动态的。列表字段可能超过 3 并且列表可以包含子项的集合(数据格式如 json)

我想转换嵌套的 ul-li html 标签。我想,我可以通过像下面这样的反思来做到这一点。但我是第一次使用反射。我的代码现在就像下面这样。我该怎么做?

    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;
    }

很可能您选择了错误的方法来完成任务。反射通常用于查询运行时代码结构,如类型、它们的字段、属性和方法。最常见的用例是为任意类型的 serialization/deserialization 创建方法。

在你的情况下,它看起来不像是任意结构——你有相当严格的数据结构,即使它支持无限(概念上)嵌套级别(如 JSON)。换句话说,你有 "tree" https://en.wikipedia.org/wiki/Tree_(data_structure).

遍历它有几种算法: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但是这个问题比你想象的要棘手一些,因为你首先需要理解这个概念。

树遍历算法通常是递归的。因此,为了正确地做到这一点,您也必须了解这个概念。

之后构建列表的代码就很简单了:

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();
}

编辑

使用给定的代码,它将在没有 children 的 <li></li> 项中生成空的 <ul></ul> 标签。所以我做了一个小改动,添加了一个条件,只在有 children.

时才创建子列表

代码:

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>");
        }
    }