Как привязать анализ HTML (HAP) к шаблону данных ListBox - PullRequest
0 голосов
/ 04 сентября 2011

В настоящее время я использую приведенный ниже код для анализа HTML-ссылки с помощью HTML Agility Pack для WP7.

РЕДАКТИРОВАТЬ ******************************** Код с предлагаемыми изменениями

void client_DownloadStringCompleted (отправитель объекта, DownloadStringCompletedEventArgs e) { var html = e.Result;

var doc = new HtmlDocument();
    doc.LoadHtml(html);

var list = doc.DocumentNode.Descendants("div").ToList();


var node = doc.DocumentNode.Descendants("div")
    .FirstOrDefault(x => x.Id == "FlightInfo_FlightInfoUpdatePanel")
    .Element("table")
    .Element("tbody")
    .Elements("tr").Select(n => new Flight()
    {
        Airline = n.Element("td").Single(j => j.Attribute("class") == "airline").Value,
        FlightType = n.Element("td").Single(j => j.Attribute("class") == "airline").Value,
        Time = n.Element("td").Single(j => j.Attribute("class") == "airline").Value,
    }

    );

Это выводит нижеследующее в просмотрщик прокрутки

Output

В каждой строке есть несколько тд для рейса, времени, авиакомпании и т. Д. Я хотел бы привязать внутренний текст тд к списку данных шаблона.

Вот пример того, как я думаю, XAML будет выглядеть

<ListBox Margin="6,6,-12,0" Name="listBox1">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Margin="0,0,0,17" Width="432" Height="Auto">

                            <TextBlock Text="{Binding Airline}" Foreground="#FF4BCCF5" FontSize="24" />
                            <TextBlock Text="{Binding Flight}" TextWrapping="Wrap" FontSize="22" Foreground="#FF969696" />
                            <TextBlock Text="{Binding Time}" TextWrapping="Wrap" FontSize="20" Foreground="#FF05C16C" />
                            <TextBlock Text="{Binding Origin}" TextWrapping="Wrap" FontSize="20" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>

HTML Пример:

 <tr class="">
 <td class="airline"><img src="/images/airline logos/NZ.gif" title="AIR NEW ZEALAND LIMITED. " alt="AIR NEW ZEALAND LIMITED. " /></td>
 <td class="flight">NZ8</td>
 <td class="codeshare">&nbsp;</td>
 <td class="origin">San Francisco</td>
 <td class="date">01 Sep</td>
 <td class="time">17:15</td>
 <td class="est">18:00</td>
 <td class="status">DEPARTED</td>
 </tr>

Итак, вопрос в том, как связать каждый результат td с отдельным текстовым блоком?

Ответы [ 2 ]

0 голосов
/ 04 сентября 2011
public class Flight
{    
    public string Airline { get; set; }
    public string Flight { get; set; }
    public DateTime Time { get; set; }    
}

Это ваш код:

var node = doc.DocumentNode.Descendants("div")
        .FirstOrDefault(x => x.Id == "FlightInfo_FlightInfoUpdatePanel")
        .Element("table")
        .Element("tbody")
        .Elements("tr").Aggregate("Flight list\n", (acc, n) => acc + "\n" + n.OuterHtml);

После

List<Flight> flightList=new List<Flight>();
foreach (HtmlNode tr in node){
    flightList.Add(new Flight(){    
        Airline=tr.Descendants("td")
            .FirstOrDefault(f=>f.Attributes["class"].Value=="airline").InnerHtml,
        Flight=tr.Descendants("td")
            .FirstOrDefault(f=>f.Attributes["class"].Value=="flight").InnerText
// Insert other properties here
    });    
}

listbox1.ItemsSource=flightList;
0 голосов
/ 04 сентября 2011

Вы можете создать простой объект модели, который вы привязываете к своему пользовательскому интерфейсу:

public class Flight
{    
    public string Airline { get; set; }
    public string Flight { get; set; }
    public DateTime Time { get; set; }    
}

Затем используйте проекцию Выбрать, чтобы преобразовать ваш документ в список рейсов:

var node = doc.DocumentNode.Descendants("div")
    .FirstOrDefault(x => x.Id == "FlightInfo_FlightInfoUpdatePanel")
    .Element("table")
    .Element("tbody")
    .Elements("tr").Aggregate("Flight list\n", (acc, n) => acc + "\n" + n.OuterHtml);

List<Flight> flights = node.Elements("td").Select(i =>
           new Flight()
           {
              Airline = i.Element("td").Single(j => j.Attribute("class") == "airline").Value,
              Flight = i.Element("td").Single(j => j.Attribute("class") == "flight").Value,
              ...
           }

Затем свяжите этот список экземпляров Flight с вашим пользовательским интерфейсом.

Я не знаком с HTML Agility Pack, поэтому я предполагаю, что его Linq API похож или аналогичен Linq to XML.Возможно, вам придется немного изменить приведенный выше код запроса, но общий подход должен подойти.

...