使节点在以下兄弟中处于相同位置

时间:2014-02-01 21:15:06

标签: c# xpath html-agility-pack

我正在使用HTML敏捷包来解析一些HTML,其中一个片段的形式如下:

<tbody>
 <tr>
  <td><a href="remotelink1"><img /></a></td><td></td>
  <td><a href="site2"><img /></a></td><td></td>
  <td><a href="link3"><img /></a></td><td></td>
  <td><a href="site4"><img /></a></td><td></td>
  <td><a href="link5"><img /></a></td>
 </tr>
 <tr>
  <td style="text-align: left;" width="200" height="45">a<br>b<br>c</td><td width="17"></td>
  <td style="text-align: left;" width="200">d<br>e<br>f</td><td width="57"></td>
  <td style="text-align: left;" width="200">g<br>h<br>i</td><td width="57"></td>
  <td width="200">j<br>k<br>l</td><td width="57"></td>
  <td width="200">m<br>n<br>o</td>
 </tr>
 <tr>
  <td><a href="link6"><img /></a></td><td></td>
  <td><a href="site7"><img /></a></td><td></td>
  <td><a href="remotelink8"><img /></a></td><td></td>
  <td><a href="site9"><img /></a></td><td></td>
  <td><a href="link10"><img /></a></td>
 </tr>
 <tr>
  <td style="text-align: left;" width="200" height="45">p<br>q<br>r</td><td width="17"></td>
  <td style="text-align: left;" width="200">s<br>t<br>u</td><td width="57"></td>
  <td style="text-align: left;" width="200">v<br>w<br>x</td><td width="57"></td>
  <td width="200">y<br>z<br>aa</td><td width="57"></td>
  <td width="200">ab<br>ac<br>ad</td>
 </tr>

我面临的挑战是将每个单元格与其“下方”的行相关联(即,在以下兄弟节点中与父节点相同的位置)。即我想将链接“remotelink1”与节点a<br>b<br>c和“site2”与d<br>e<br>f等关联。

我只能得到包含链接的单元格:

foreach (var item in doc.DocumentNode.SelectNodes("//div[@class='entry-content']/table/tbody/tr/td[a[@href]]"))

但我正努力让细胞位于下面,我能得到的最接近的是:

var detail = item.SelectSingleNode("../following-sibling::tr/td[position()]");

但是这会获得迭代节点的位置,而不是其父节点中的item节点。我可以使用XPath表达式将源节点的位置传递给谓词,以查找下面的单元格吗?

1 个答案:

答案 0 :(得分:2)

我想出了这些丑陋的命题:

//tr[td[a[@href="remotelink1"]]]
 /following-sibling::tr[1]
     /td[ position() = count(//tr/td[a[@href="remotelink1"]]
                                 /preceding-sibling::td) + 1]

//tr[td[a[@href="site2"]]]
 /following-sibling::tr[1]
     /td[ position() = count(//tr/td[a[@href="site2"]]
                                 /preceding-sibling::td) + 1]
  • 使用包含所需链接的tr定位td
  • 选择“以下兄弟tr元素
  • 限制第一个下一个兄弟
  • 寻找孩子td元素
  • 并根据您想要的链接过滤那些位置等于td的前一个兄弟td的数量,+1,因为XPath位置从0开始

我不知道HTML敏捷包是否支持XPath变量,但您可以将变量更改为“remotelink1”,然后将“site2”更改为2 [@href=...]

中的变量