c# 使用 StringBuilder 列出 HTML table

c# list to HTML table using StringBuilder

在 Stack overflow 社区的帮助下,我已经能够从 XML 文档中获取一些数据并使用以下代码将其添加到列表中。

String URLString = "https://api3.libcal.com/api_hours_grid.php?iid=4246&format=xml&weeks=1&systemTime=0";
XDocument xdoc = new XDocument();
xdoc = XDocument.Load(URLString);    

var location = (from p in xdoc.Descendants("location")
                from s in p.Descendants("week").Elements()            
                select new
                {

                    CampusName = (string)p.Element("name"),
                    WeekD = (string)s.Element("date"),
                    OpenHours = (string)s.Element("rendered"),
                    Day = s.Name.LocalName

                }).ToList();

效果很好,我可以使用以下内容输出到无序列表

string currentLocation = "";

foreach (var item in location)
{
    if (item.CampusName != currentLocation)
    {
        <h2>@item.CampusName</h2>
        currentLocation = @item.CampusName;
    }
    <ul>
        <li>@item.WeekD - @item.OpenHours</li>
    </ul>
} 

但是,在查看我的要求后,我觉得使用 HTML Table 可以更好地显示数据。我尝试了几种不同的方法使用 String builder 来实现这个

string dayStop = "Sunday";    
StringBuilder sb = new StringBuilder();
sb.Append("<TABLE>\n");
sb.Append("<TR>\n");
foreach (var item in location)
{

    if (item.Day != dayStop)

    {
        sb.Append("<TH>\n");
        sb.Append(@item.Day);
        sb.Append("</TH>\n");

        //dayStop = @item.Day;
    }

}

sb.Append("</TR>\n");

sb.Append("<TR>\n");

sb.Append("<TD>\n");
sb.Append(@item.CampusName);
sb.Append("</TD>\n");
sb.Append("<TD>\n");
sb.Append(@item.OpenHours);
sb.Append("</TD>\n");

sb.Append("</TR>\n");
sb.Append("</TABLE > ");
}
Html.Raw(sb)

但它不起作用。我希望 @item.Day 的值填充 TH 的值,但是由于我列表中的每个项目都包含每个 @item.CampusName 的值日值,所以我最终得到了一大堆不必要的 @item.Day 值,我觉得 foreach 在这里不是正确的答案。我想要结束的是类似于以下片段的内容;

  <table>
    <tr>
    <th>
    Location
    </th>
    <th>
    Sunday
    </th>
    <th>
    Monday
    </th>
    <th>
    Tueday
    </th>
    </tr>
    <tr>
    <td>
    Campus 1
    </td>
    <td>
    9 - 5
    </td>
    <td>
    9 - 5
    </td>
    <td>
    9 - 5
    </td>
    </tr>
    <tr>
    <td>
    Campus 2
    </td>
    <td>
    9 - 5
    </td>
    <td>
    9 - 5
    </td>
    <td>
    9 - 5
    </td>
    </tr>
    </table>

在你的 xml 中你有多个 Days 所以对于 th 你必须与那些日子截然不同并渲染 对于连续的 tr,您必须按其 CampusName

对每一行进行分组

试试下面的代码,这将帮助您获得想要的结果。

最佳做法是在您的操作方法中编写以下代码,并使用 viewbag 或 viewmodel 将结果传递给您的 razor 视图。您发布的相关代码在 razor 视图中,所以我也在 razor 中实现了我的代码。

<div>
    @{
        String URLString = "https://api3.libcal.com/api_hours_grid.php?iid=4246&format=xml&weeks=1&systemTime=0";
        XDocument xdoc = new XDocument();
        xdoc = XDocument.Load(URLString);


        var location = (from p in xdoc.Descendants("location")
                        from s in p.Descendants("week").Elements()
                        select new
                        {
                            CampusName = (string)p.Element("name"),
                            WeekD = (string)s.Element("date"),
                            OpenHours = (string)s.Element("rendered"),
                            Day = s.Name.LocalName
                        }).ToList();


        string dayStop = "Sunday";

        StringBuilder sb = new StringBuilder();
        sb.Append("<table>\n");
        sb.Append("<tr>\n");


        string currentLocation = "";

        foreach (var item in location.GroupBy(x => x.Day).Select(x => x.First()))
        {
            if (item.CampusName != currentLocation)
            {
                sb.Append("<th style='width:150px;'>\n");
                sb.Append("Location");
                sb.Append("</th>\n");
                currentLocation = item.CampusName;
            }

            if (item.Day != dayStop)
            {
                sb.Append("<th style='width:150px;'>\n");
                sb.Append(item.Day);
                sb.Append("</th>\n");
            }

        }

        sb.Append("</tr>\n");


        currentLocation = "";

        foreach (var item in location.GroupBy(x => x.CampusName))
        {
            sb.Append("<tr>\n");
            foreach (var innerItem in item)
            {
                if (innerItem.CampusName != currentLocation)
                {
                    sb.Append("<td>\n");
                    sb.Append(innerItem.CampusName);
                    sb.Append("</td>\n");
                    currentLocation = innerItem.CampusName;
                }


                if (innerItem.Day != dayStop)
                {
                    sb.Append("<td>\n");
                    sb.Append(innerItem.OpenHours);
                    sb.Append("</td>\n");
                }
            }

            sb.Append("</tr>\n");

        }

        @Html.Raw(sb.ToString());
    }

</div>

OR 你也可以使用 html 来剃刀视图,因为你不需要使用 StringBuilder 这比上面更容易代码。

@{
    string currentLocation1 = "";
    string currentLocation2 = "";
    string dayStop1 = "Sunday";
}

<table>
    <thead>
        <tr>
            @foreach (var item in location.GroupBy(x => x.Day).Select(x => x.First()))
            {
                if (item.CampusName != currentLocation1)
                {
                    <th style='width:150px;'>Location</th>
                    currentLocation1 = item.CampusName;
                }

                if (item.Day != dayStop1)
                {
                    <th style='width:150px;'>@item.Day</th>
                }
            }
        </tr>
    </thead>
    <tbody>
        @foreach (var item in location.GroupBy(x => x.CampusName))
        {
            <tr>
                @foreach (var innerItem in item)
                {
                    if (innerItem.CampusName != currentLocation2)
                    {
                        <td>@innerItem.CampusName</td>
                        currentLocation2 = innerItem.CampusName;
                    }


                    if (innerItem.Day != dayStop1)
                    {
                        <td>@innerItem.OpenHours</td>
                    }
                }

            </tr>
        }
    </tbody>
</table> 

以上两个片段的输出: