2016-10-31 2 views
1

Я использую следующий код для разбора HTML таблиц из HTML-файла в набор данных:Игнорирования тегов в XPATH, используя HTML ловкость пакет

Public Function GetDataSet(html As String) As DataSet 
Dim ds As DataSet = New DataSet 
Dim htmldoc As New HtmlAgilityPack.HtmlDocument 
htmldoc.LoadHtml(html) 
Dim tables = htmldoc.DocumentNode.SelectNodes("//table/tr") _ 
           .GroupBy(Function(x) x.ParentNode) 
For i As Integer = 0 To tables.Count - 1 
    Dim rows = tables(i).ToList() 
    ds.Tables.Add(String.Format("Table {0}", i)) 
    Dim headers = rows(0).Elements("th").Select(Function(x) x.InnerText.Trim).ToList() 
    For Each Hr In headers 
     ds.Tables(i).Columns.Add(Hr) 
    Next 
    For j As Integer = 1 To rows.Count - 1 
     Dim row = rows(j) 
     Dim dr = row.Elements("td").Select(Function(x) x.InnerText.Trim).ToArray() 
     ds.Tables(i).Rows.Add(dr) 
    Next 
Next 
Return ds 
End Function 

и она отлично работает. Но когда Есть тег помещается внутри <Table> Tag перед тем <tr> тегом таблица не разобраны

Простой пример:

<html> <head><title>Test</title></head> <body> <div>Contents:</div> <table> <tr> <th>Column1</th> <th>Column2</th> </tr> <tr> <td>1</td> <td>11</td> </tr> <tr> <td>2</td> <td>22</td> </tr> </table> <table> <tbody> <tr> <th>Column1</th> <th>Column2</th> <th>Column3</th> </tr> <tr> <td>a</td> <td>aa</td> <td>aaa</td> </tr> <tr> <td>b</td> <td>bb</td> <td>bbb</td> </tr> </tbody> </table> <table> <div> <tr> <th>Column1</th> <th>Column2</th> <th>Column3</th> </tr> <tr> <td>a</td> <td>aa</td> <td>aaa</td> </tr> <tr> <td>b</td> <td>bb</td> <td>bbb</td> </tr> </div> </table> </body> </html>

В этом примере только первая таблица разобранной.

Мой вопрос заключается в том, чтобы игнорировать любой тег между <Table> тегом и <tr> тегом в следующей строке коды:

Dim tables = htmldoc.DocumentNode.SelectNodes("//table/tr") _ 
          .GroupBy(Function(x) x.ParentNode) 

и все таблицы будут обрабатываться.

ответ

2

Вы можете использовать // выбрать из всех потомков:

Dim rows = htmldoc.DocumentNode.SelectNodes("//table//tr"); 

Также на основе ваших требований, то кажется, что лучше сгруппировать результат на основе первого предка table, потому что родитель tr может быть tbody или thead и вам необходимо сгруппировать строки в таблицах:

Dim tables = htmldoc.DocumentNode.SelectNodes("//table//tr") _ 
        .GroupBy(Function(x) x.Ancestors("table").First()) 
+1

чтобы узнать больше о XPath вы посмотрите на может [XPath синтаксис] (http://www.w3schools.com/xml/xpath_syntax.asp) , –