2011-07-06 64 views
1

我正在使用HtmlAgilityPack从网站获取一些Html。HtmlAgilityPack算法问题

这里是接收到的HTML:

<table class="table"> 
<tr> 
    <td> 
     <table class="innertable">...</table> 
    </td> 
</tr> 
<tr> 
    <td colspan="2"><strong>Contact</strong></td> 
</tr> 
<tr> 
    <td colspan="2">John Doe</td> 
</tr> 
<tr> 
    <td colspan="2">Jane Doe</td> 
</tr> 
<tr> 
    <td colspan="2">&nbsp;</td> 
</tr> 
<tr> 
    <td><strong>Units</strong></td> 
    <td>32</td> 
</tr> 
<tr> 
    <td><strong>Year</strong></td> 
    <td>1998</td> 
</tr> 
</table> 

上下文:

我用下面的代码来获取第一:

var table = document.DocumentNode.SelectNodes("//table[@class='table']").FirstOrDefault(); 

我m使用以下代码获取内部表格:

var innerTable = table.SelectNodes("//table[@class=innertable]").FirstOrDefault(); 

到目前为止好!

我需要从第一个表和一些内部表中获取一些信息。 自从我与第一个表,我需要信息开始跳过第一行(持有内表),所以我做到以下几点:

var tableCells = table.SelectNodes("tr[position() > 1]/td"); 

因为我现在都从细胞不包括内部表的第一个表,我开始做以下几点:

string contact1 = HttpUtility.HtmlDecode(tableCells[1].InnerHtml); 
string contact2 = HttpUtility.HtmlDecode(tableCells[2].InnerHtml); 

string units = HttpUtility.HtmlDecode(tableCells[5].InnerHtml); 
string years = HttpUtility.HtmlDecode(tableCells[7].InnerHtml); 

问题:

我得到我想要的值硬编码 tableCells []中的索引没有考虑布局会移动...不幸的是,它确实移动了。

在某些情况下,我没有“Jane Doe”行(如上面的Html所示),这意味着我可能可能没有两个联系人。

因此,我无法对索引进行硬编码,因为我最终可能会在错误的变量中输入错误的数据。

所以我需要改变我的做法......

有谁知道我怎么能完善我的算法,以便它可以考虑到这样的事实,我可能有一个两个触点,也许不能用硬编码索引?

在此先感谢!

vlince

回答

1

从来没有一种独特的解决方案来解决这类问题。下面是似乎做某种它虽然一个XPATH:

 HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument(); 
     doc.Load(yourHtmlFile); 

     doc.Save(Console.Out); 

     foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//tr[td/strong/text() = 'Contact']/following-sibling::tr/td/text()[. != '&nbsp;']")) 
     { 
      Console.WriteLine(node.OuterHtml); 
     } 

将显示此:

John Doe 
Jane Doe 
32 
1998 
+0

是西蒙,你是正确的...有没有做事方式很独特: - ) 感谢您的文章,它确实让我想到(重新思考)我的算法,并且我喜欢您展示的内容!也许我需要阅读更多关于XPATH的内容才能像你一样提出表达式。非常感谢! – Vlince