从 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>");
}
}
我有如下列表(示例):
但此列表只是逻辑示例。该列表应该是动态的。列表字段可能超过 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>");
}
}