Ken-in-California Ответов: 1

C# - использование htmlagilitypack для перемещения данных HTML-таблицы в список Привязок


Я извлекаю данные с веб-сайта, где они организованы в виде таблицы. Первые две строки выглядят так (я удалил некоторую информацию о стиле):

<table id="loads">
   <thead>
   <tr class="tableHeading">
     <th><a original='Load ID'></a></th>
     <th><a original='# of cars'></a></th>
     <th><a original='Year/Make/Model'></a></th>
     <th><a original='Origin City'></a></th>
     <th><a original='Origin State'></a></th>
     <th><a original='Destination City'></a></th>
     <th><a original='Destination State'></a></th>
     <th><a original='Mileage'></a></th>
     <th><a original='Price per Shipment'></a></th>
     <th><a original='Price per Mile'></a></th>
     <th>View</th>
     <th><a original='Comments'></a></th>
   </tr>
   </thead>

   <tbody>
   <tr>
     <td>123456789</td>
     <td>1</td>
     <td>2015 GMC TERRAIN SLE</td>
     <td>Los Angeles</td>
     <td>CA</td>
     <td>San Francisco</td>
     <td>CA</td>
     <td>400</td>
     <td>$400</td>
     <td>$1</td>
     <td>
        <a href="/ViewLoad.asp?nload_id=123456789&npickup_code=">
         <img src="/images/icons/view.gif" >
         </a>
     </td>
     <td>Some Text</td>
   </tr>


В каждой строке 12 ячеек - все строки, кроме 11-й, что является одной из главных причин, по которой я публикую этот вопрос.

Что я уже пробовал:

Я создал класс, который имеет 13 строковых свойств. Дополнительный (который я сделал первым) - это свойство статуса, которое будет новым или старым. Позже я собираюсь сделать кое-что с новыми строками, но сейчас это не моя проблема.

Итак, теперь я хочу захватить внутренний текст каждой ячейки (кроме 11) и присвоить строку массиву. Вот мои шаги:

string collect = webBrowser1.Document.Body.InnerHtml;
string data = WebUtility.HtmlDecode(collect);
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();
htmlDoc.LoadHtml(data);
HtmlNodeCollection rows = htmlDoc.DocumentNode.SelectNodes("//table[@id='loads']//tbody//tr");


Примечание-Я проверял до этого момента, и до сих пор все это работает, и коллекция строк собирает все строки в таблице, кроме заголовка (я показал только одну строку без заголовка выше, но их много).

На следующем шаге я теряюсь. Я пытаюсь поместить строки ячеек в массив строк и в список Привязок, настроенный на уровне формы:

BindingSource source = new BindingSource(); /// this binds to the dataviewgrid
BindingList<Load> list = new BindingList<Load>();
BindingList<Load> listDeleted = new BindingList<Load>();
List<Load> sortList = new List<Load>();


Вот мой код:

int rowIndex = 0;

foreach (HtmlNode row in rows)
{
    int columnIndex = 0;
    string[] rowData = new string[13];

    foreach (HtmlNode cell in row.ChildNodes)
    {
        if (columnIndex != 0 && columnIndex != 11)
        {
            rowData[columnIndex - 1] = cell.InnerText;
        }

        rowData[11] = cell.FirstChild.Attributes["href"].Value;

        MessageBox.Show(rowData[11]);
        columnIndex++;
     }

     Load newLoad = new Load(rowData);

     if (!list.Contains(newLoad) && !listDeleted.Contains(newLoad))
     {
         list.Add(newLoad);
         updated = true;
     }
     else
     {
         int itemIndex = list.IndexOf(newLoad);
         if (itemIndex > 0)
         {
             if (!list[itemIndex].Comments.Equals(newLoad.Comments))
                 {
                     list[itemIndex].Comments = newLoad.Comments;
                     list[itemIndex].Status = "MODIFIED";
                     updated = true;
                 }
          }
       }
       rowIndex++;
   }

}

Я не уверен, что я делаю неправильно в этом последнем блоке кода - и очень ценю любую помощь.

Suvabrata Roy

в чем именно заключается ваша проблема, я не могу понять.

Ken-in-California

Он работает до того момента (выше), когда я создаю массив "rowData" и пытаюсь присвоить этому массиву строки внутреннего текста ячейки таблицы. (Раздел с вложенными циклами foreach).
Nodecollection под названием "rows" правильно собирает все элементы строк, но когда я пытаюсь получить узлы ячеек из этой коллекции в массив, ничего не происходит.

Как только я получу данные в массив, мне все равно нужно будет поместить их в bindinglist - но я еще не там. Прямо сейчас моя проблема-добраться до массива.

Richard Deeming

rowData[11] = cell.FirstChild.Attributes["href"].Value;

Вы выполняете эту строку для каждый клетка, но только одна клетка имеет ребенка <a> элемент. Вам нужно изменить свой код так, чтобы он только пытался извлечь это значение из правильной ячейки.

Возможно, Вам также потребуется проверить, <a> элемент действительно является первым дочерним элементом, или же HAP включает пробел в качестве текстового узла.

Ken-in-California

Ричард-Спасибо.
Код почти точно такой же, как показано выше - я только удалил некоторые стили и изменил текст (например, число, которое я изменил на "123456789".
Вы, кажется, проверяете мое использование свойства firstchild класса HTMLNode - я никогда не использовал его раньше и не был уверен, что это правильный путь.
Можете ли вы порекомендовать другой способ получить эту текстовую строку "href"?

Richard Deeming

Как я уже сказал, вам нужно будет изменить свой код так, чтобы эта строка выполнялась только для ячейки, содержащей якорь. В настоящее время он выполняется для каждой ячейки, что не будет работать.

1 Ответов

Рейтинг:
6

Ken-in-California

Оказалось, что веб-сайт возвращал некоторые escape-символы, которые появлялись в виде дополнительных строк, так что я смог справиться с этим, переписав свои условные обозначения.
Спасибо, что нашел время ответить на мой вопрос, Ричард, это помогло.