如何将 HTML 解析 (HAP) 绑定到 ListBox DataTemplate

发布于 2024-12-02 17:26:40 字数 2544 浏览 0 评论 0原文

我当前正在运行以下代码,以使用适用于 WP7 的 HTML Agility Pack 来解析 HTML 链接。

编辑******************************** 建议更改的代码

void client_DownloadStringCompleted(object sender, 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

每行中有多个 td,用于航班、时间、航空公司等。想要做的是将每个 td 内部文本绑定到列表框 dataTemplate。

下面是我认为 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 结果绑定到其自己的文本块?

I am currently running the below code to parse an HTML link using HTML Agility Pack for WP7.

EDIT ******************************** Code with suggested changes

void client_DownloadStringCompleted(object sender, 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,
    }

    );

This outputs the below into a scrollviewer

Output

There are multiple td's in each line for flight, time, airline etc.. What I would like to do is to bind each td inner text to a listbox dataTemplate.

Here is an example of what I think the XAML would look like

<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 Example:

 <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"> </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>

So the question is: How do I bind each td results to its own text block?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江挽川 2024-12-09 17:26:40
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;
public class Flight
{    
    public string Airline { get; set; }
    public string Flight { get; set; }
    public DateTime Time { get; set; }    
}

This is your code:

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);

After

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;
行雁书 2024-12-09 17:26:40

您可以创建一个绑定到 UI 的简单模型对象:

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

然后使用 Select 投影将文档转换为航班列表:

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 实例列表绑定到您的 UI。

我不熟悉 HTML Agility Pack,因此我假设它的 Linq API 与 Linq to XML 类似或相同。您可能需要稍微调整上面的查询代码,但一般方法应该没问题。

You could create a simple model object that you bind to your UI:

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

Then use a Select projection to convert your document into a list of flights:

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,
              ...
           }

Then bind this list of Flight instances to your UI.

I am not familiar with HTML Agility Pack, so I am assuming that its Linq API is similar, or the same as Linq to XML. You might have to tweak the query code above a little bit, but the general approach should be fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文