C# 在ASP.NET C中将HTML表解析为JSON#

C# 在ASP.NET C中将HTML表解析为JSON#,c#,asp.net,json,xml,html-table,C#,Asp.net,Json,Xml,Html Table,我有个问题。我有一个调查生成器,其中包含不同类型的问题(列表、复选框、下拉列表…),还有一个需要填写的表格。现在的问题是存储表,我的数据库中有3个不同的表,以后创建表有点复杂。我正在尝试这样做,使用JavaScript编辑器,这样用户就可以像word一样创建表。在我的代码中,我以字符串的形式接收表标记,并希望将其作为JSON存储在数据库中 这里有一段代码将表转换为DataSet对象,然后从这里我可以使用库JSON.NET转换为XML,从这里转换为JSON。所有这些都可以正常工作,但问题是当表有“

我有个问题。我有一个调查生成器,其中包含不同类型的问题(列表、复选框、下拉列表…),还有一个需要填写的表格。现在的问题是存储表,我的数据库中有3个不同的表,以后创建表有点复杂。我正在尝试这样做,使用JavaScript编辑器,这样用户就可以像word一样创建表。在我的代码中,我以字符串的形式接收表标记,并希望将其作为JSON存储在数据库中

这里有一段代码将表转换为DataSet对象,然后从这里我可以使用库JSON.NET转换为XML,从这里转换为JSON。所有这些都可以正常工作,但问题是当表有“colspan”和“rowspan”参数时,它们就不能工作了。您能帮我完成这段代码吗?这样每个人都可以以它为例,用C#将HTML表解析为JSON

受保护的无效页面加载(对象发送方,事件参数e)
{
字符串表=@“
ProjectCountryHeader 1标题2
子标题1子标题2子标题3子标题4
子标题1页次
原子吸收光谱
尤西斯
阿皮
阿穆克
SMRTU
厘米
";
DataSet DataSet=HtmlTableParser.ParseDataSet(表);
StringWriter sw=新的StringWriter();
WriteXml(sw,XmlWriteMode.IgnoreSchema);
XmlDocument xd=新的XmlDocument();
LoadXml(sw.ToString());
字符串jsonText=JsonConvert.SerializeXmlNode(xd).Replace(“\ux0020\ux0”,”);
}
/// 
///HtmlTableParser将html字符串的内容解析为System.Data数据集或DataTable。
/// 
公共类HtmlTableParser
{
private const RegexOptions ExpressionOptions=RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase;
private const string CommentPattern=“”;
private const string TablePattern=“]*>(.*?”;
private const string HeaderPattern=“]*>(.*?”;
private const string RowPattern=“]*>(.*?”;
私有常量字符串CellPattern=“]*>(.*?”;
/// 
///给定一个包含n个表的HTML字符串,将其解析为包含n个数据表的数据集。
/// 
///包含n个HTML表的HTML字符串
///包含输入HTML中每个HTML表的DataTable的数据集
公共静态数据集ParseDataSet(字符串html)
{
数据集=新数据集();
MatchCollection tableMatches=Regex.Matches(
无注释(html),
表格模式,
表达选择);
foreach(在tableMatches中匹配tableMatch)
Add(ParseTable(tableMatch.Value));
返回数据集;
}
/// 
///给定包含单个表的HTML字符串,解析该表以形成DataTable。
/// 
///包含单个HTML表的HTML字符串
///与输入HTML表匹配的数据表
公共静态数据表ParseTable(字符串表HTML)
{
string tableHtmlWithoutComments=WithoutComments(tableHtml);
DataTable=新的DataTable();
MatchCollection rowMatches=Regex.Matches(
无注释的表格HTMLW,
行模式,
表达选择);

dataTable.Columns.AddRange(tableHtmlWithoutComments.Contains)(“这闻起来像是非常糟糕的事情”。为什么要使用正则表达式来清理HTML?堆栈上溢出与此相关。不要这样做

您将此HTML解析为此DataTable的要求对我来说没有实际意义。在要求您现在将其解析为JSON之后,您将如何处理此HTML表?从您的问题来看,这似乎是一个相当简单的调查编辑器


如果您真的需要将这些数据解析为对象,并将此表中的每个字段存储到数据库中,请告诉我们原因。这样做是可能的,但我强烈建议您重新考虑解析HTML。

这听起来像是非常糟糕的事情。。为什么要使用正则表达式清理HTML?T他在堆栈溢出与这件事有关。不要这样做

您将此HTML解析为此DataTable的要求对我来说没有实际意义。在要求您现在将其解析为JSON之后,您将如何处理此HTML表?从您的问题来看,这似乎是一个相当简单的调查编辑器


如果您真的需要将这些数据解析为对象,并将此表中的每个字段存储到数据库中,请告诉我们原因。这样做是可能的,但我强烈建议您重新考虑解析HTML。

我从以下代码中获得了将数据集解析为XML的代码:将HTML标记存储在数据库中有什么问题?这不是一个正如我所寻找的,JSON是干净的。我以后可以使用JSON作为一个对象,而且更容易使用。数据存储在数据库中后,将如何处理数据?从哪里接收表标记?如果在客户端创建表,然后将标记传递给codebehind,这可能不是最简单的方法。在客户端创建JSON对象可能更容易客户端并传递它(而不是表字符串)到codebehind。我从以下代码中获得将数据集解析为XML的代码:在db中存储html标记有什么问题?没有我想要的那么干净。我以后可以使用JSON作为对象,并且更易于使用。在数据存储到db中后,将如何处理数据?从哪里接收表标记?如果在客户端上创建表然后将标记传递给codebehind——这可能不是最简单的方法
protected void Page_Load(object sender, EventArgs e)
{
    string table = @"<table>
                <tbody><tr>
                    <th rowspan='4'>Project</th><th rowspan='4'>Country</th><th colspan='3' rowspan='1'>Header 1</th><th colspan='2' rowspan='1'>Header 2</th>
                </tr><tr>
                    <th colspan='1' rowspan='1'>Child Header 1</th><th colspan='2' rowspan='1'>Child Header 2</th><th colspan='1' rowspan='3'>Child Header 3</th><th colspan='1' rowspan='3'>Child Header 4</th>
                </tr><tr>
                    <th colspan='1' rowspan='2'>Child Child Header 1</th><th colspan='1' rowspan='1'>tee</th><th colspan='1' rowspan='2'>ssss</th>
                </tr><tr>
                    <th colspan='1' rowspan='1'>aas</th>
                </tr><tr>
                    <td>EUS</td><td>ES</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                </tr><tr>
                    <td>ARP</td><td>IE</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                </tr><tr>
                    <td>ARM</td><td>UK</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                </tr><tr>
                    <td>SMRT</td><td>US</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                </tr><tr>
                    <td>CM</td><td></td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
                </tr>
            </tbody></table>";

    DataSet dataSet = HtmlTableParser.ParseDataSet(table);
    StringWriter sw = new StringWriter();
    dataSet.WriteXml(sw, XmlWriteMode.IgnoreSchema);
    XmlDocument xd = new XmlDocument();
    xd.LoadXml(sw.ToString());

    string jsonText = JsonConvert.SerializeXmlNode(xd).Replace("_x0020_", " ");
}

/// <summary>
/// HtmlTableParser parses the contents of an html string into a System.Data DataSet or DataTable.
/// </summary>
public class HtmlTableParser
{
    private const RegexOptions ExpressionOptions = RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnoreCase;
    private const string CommentPattern = "<!--(.*?)-->";
    private const string TablePattern = "<table[^>]*>(.*?)</table>";
    private const string HeaderPattern = "<th[^>]*>(.*?)</th>";
    private const string RowPattern = "<tr[^>]*>(.*?)</tr>";
    private const string CellPattern = "<td[^>]*>(.*?)</td>";

    /// <summary>
    /// Given an HTML string containing n table tables, parse them into a DataSet containing n DataTables.
    /// </summary>
    /// <param name="html">An HTML string containing n HTML tables</param>
    /// <returns>A DataSet containing a DataTable for each HTML table in the input HTML</returns>
    public static DataSet ParseDataSet(string html)
    {
        DataSet dataSet = new DataSet();
        MatchCollection tableMatches = Regex.Matches(
            WithoutComments(html),
            TablePattern,
            ExpressionOptions);

        foreach (Match tableMatch in tableMatches)
            dataSet.Tables.Add(ParseTable(tableMatch.Value));

        return dataSet;
    }

    /// <summary>
    /// Given an HTML string containing a single table, parse that table to form a DataTable.
    /// </summary>
    /// <param name="tableHtml">An HTML string containing a single HTML table</param>
    /// <returns>A DataTable which matches the input HTML table</returns>
    public static DataTable ParseTable(string tableHtml)
    {
        string tableHtmlWithoutComments = WithoutComments(tableHtml);

        DataTable dataTable = new DataTable();

        MatchCollection rowMatches = Regex.Matches(
            tableHtmlWithoutComments,
            RowPattern,
            ExpressionOptions);

        dataTable.Columns.AddRange(tableHtmlWithoutComments.Contains("<th")
                                       ? ParseColumns(tableHtml)
                                       : GenerateColumns(rowMatches));

        ParseRows(rowMatches, dataTable);

        return dataTable;
    }

    /// <summary>
    /// Strip comments from an HTML stirng
    /// </summary>
    /// <param name="html">An HTML string potentially containing comments</param>
    /// <returns>The input HTML string with comments removed</returns>
    private static string WithoutComments(string html)
    {
        return Regex.Replace(html, CommentPattern, string.Empty, ExpressionOptions);
    }

    /// <summary>
    /// Add a row to the input DataTable for each row match in the input MatchCollection
    /// </summary>
    /// <param name="rowMatches">A collection of all the rows to add to the DataTable</param>
    /// <param name="dataTable">The DataTable to which we add rows</param>
    private static void ParseRows(MatchCollection rowMatches, DataTable dataTable)
    {
        foreach (Match rowMatch in rowMatches)
        {
            // if the row contains header tags don't use it - it is a header not a row
            if (!rowMatch.Value.Contains("<th"))
            {
                DataRow dataRow = dataTable.NewRow();

                MatchCollection cellMatches = Regex.Matches(
                    rowMatch.Value,
                    CellPattern,
                    ExpressionOptions);

                for (int columnIndex = 0; columnIndex < cellMatches.Count; columnIndex++)
                    dataRow[columnIndex] = cellMatches[columnIndex].Groups[1].ToString();

                dataTable.Rows.Add(dataRow);
            }
        }
    }

    /// <summary>
    /// Given a string containing an HTML table, parse the header cells to create a set of DataColumns
    /// which define the columns in a DataTable.
    /// </summary>
    /// <param name="tableHtml">An HTML string containing a single HTML table</param>
    /// <returns>A set of DataColumns based on the HTML table header cells</returns>
    private static DataColumn[] ParseColumns(string tableHtml)
    {
        MatchCollection headerMatches = Regex.Matches(
            tableHtml,
            HeaderPattern,
            ExpressionOptions);

        return (from Match headerMatch in headerMatches
                select new DataColumn(headerMatch.Groups[1].ToString())).ToArray();
    }

    /// <summary>
    /// For tables which do not specify header cells we must generate DataColumns based on the number
    /// of cells in a row (we assume all rows have the same number of cells).
    /// </summary>
    /// <param name="rowMatches">A collection of all the rows in the HTML table we wish to generate columns for</param>
    /// <returns>A set of DataColumns based on the number of celss in the first row of the input HTML table</returns>
    private static DataColumn[] GenerateColumns(MatchCollection rowMatches)
    {
        int columnCount = Regex.Matches(
            rowMatches[0].ToString(),
            CellPattern,
            ExpressionOptions).Count;

        return (from index in Enumerable.Range(0, columnCount)
                select new DataColumn("Column " + Convert.ToString(index))).ToArray();
    }
}