#c#-3.0
#c #-3.0
Вопрос:
У меня есть HTML-таблица.Я хочу преобразовать это в datatable. Каков наилучший способ сделать это? Спасибо
Ответ №1:
Не разбирайте HTML самостоятельно, существуют библиотеки синтаксического анализа, которые могут сделать это за вас. В сочетании с HTML Agility Pack и LINQ вы можете быстро справиться с этим.
var doc = new HtmlDocument();
doc.Load(url);
var nodes = doc.DocumentNode.SelectNodes("//table/tr");
var table = new DataTable("MyTable");
var headers = nodes[0]
.Elements("th")
.Select(th => th.InnerText.Trim());
foreach (var header in headers)
{
table.Columns.Add(header);
}
var rows = nodes.Skip(1).Select(tr => tr
.Elements("td")
.Select(td => td.InnerText.Trim())
.ToArray());
foreach (var row in rows)
{
table.Rows.Add(row);
}
Комментарии:
1. Позаботится ли это о colspans и стилизации таблиц (css)? Похоже, что это просто переведет разметку данных и элементов
2. @user327999: нет, это просто взаимно однозначное сопоставление. В DataTables все равно нет такой вещи, AFAIK.
3. Я только что скачал HtmlAgilityPack 1.4.6 для того, чтобы сделать это. На веб-сайте говорится, что документации пока нет. Я попытался последовать приведенному здесь примеру, но получил исключение NullReferenceException при этом:
var headers = nodes[0].Elements("th").Select(th => th.InnerText.Trim());
Узлы былиnull
. Как мне использовать этот элемент управления? Где я могу найти текущую документацию по этому вопросу?4. @jp2code: Это будет зависеть от разметки, которую вы анализируете. Документации, по общему признанию, не хватает, но большинство методов имеют обычную XML-документацию, которой, насколько я проверял в последний раз, должно быть достаточно. Но я полагаю, что это было смоделировано по
XmlDocument
и связанным классам, поэтому, если вы знакомы с синтаксическим анализом XML с использованием библиотеки XML, вы должны чувствовать себя как дома.nodes
это результат вызоваHtmlNode.SelectNodes()
, который вы передаете в селекторе xpath. По-видимому, в вашем примере не было найдено таблиц с непосредственными строками.5. Я внес некоторые небольшие коррективы, чтобы они соответствовали моему столу, но все сработало отлично .. Большое вам спасибо.
Ответ №2:
…несколько лет спустя…
var nodes = doc.DocumentNode.SelectNodes("//table/tr");
строка содержит опечатку и должна быть с двойной косой чертой после слова «таблица», и все работает как по маслу
var nodes = doc.DocumentNode.SelectNodes("//table//tr");
Комментарии:
1. Это не обязательно правильно, по крайней мере, было бы неправильно классифицировать это как опечатку … и, в зависимости от ситуации, вероятно, неправильно. Большинство людей пишут таблицы,
tr
элементы которых являются прямыми дочерними элементамиtable
узла. (<table><tr>...</tr></table>
) Но подобное изменение могло бы потребоваться, если бы строки находились подtbody
элементом. Было бы правильно, если бы это было так, но я бы сказал, что это не так часто. Но это вызовет проблемы, особенно когда задействованы вложенные таблицы. Но … это чисто ситуативно … как и в данном случае.