2012-10-23 89 views
0

假設我有以下行的HTML表格,過濾器中的XPath基於叔叔

... 
<tr> 
    <th title="Library of Quintessential Memes">LQM:</th> 
    <td> 
    <a href="docs/lqm.html"><b>Intro</b></a> 
    <a href="P/P79/">79</a> 
    <a href="P/P80/">80</a> 
    <a href="P/P81/">81</a> 
    <a href="P/P82/">82</a> 
    </td> 
</tr> 
<tr> 
    <th title="Library of Boring Books">LBB:</th> 
    <td> 
    <a href="docs/lbb.html"><b>Intro</b></a> 
    <a href="R/R80/">80</a> 
    <a href="R/R81/">81</a> 
    <a href="R/R82/">82</a> 
    <a href="R/R83/">83</a> 
    <a href="R/R84/">84</a> 
    </td> 
</tr> 
... 

我想在一個<td>元素,其相關<th>的文本是一小部分選擇所有<a>元素固定標題(例如LQM,LBR和RTT)。我怎樣才能將其作爲一個XPath查詢來制定?

編輯:我正在使用Scrapy,一個Python抓取工具包,所以如果它更容易將這個查詢作爲一組較小的查詢來使用,我會樂於使用它。例如,如果我可以選擇其第一個<th>孩子與正則表達式匹配的所有<tr>元素,則選擇其餘<tr>元素的所有後代,這將是出色的。

回答

2

以下XPath將工作:

//a[contains(',LQM:,LBR:,RTT:,', 
      concat(',', ancestor::td/preceding-sibling::th, ','))] 

這在理論上可以得到一些假陽性(如果你的代碼包含引號)。

更嚴格的方式來表達就是:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="/"> 
     <xsl:for-each select="//a[ancestor::td/preceding-sibling::th[.='LQM:']] 
            |//a[ancestor::td/preceding-sibling::th[.='LBR:']] 
            |//a[ancestor::td/preceding-sibling::th[.='RTT:']]"> 
      <xsl:text> 
</xsl:text> 
      <xsl:copy-of select="."/> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:transform> 

它產生以下輸出:

//a[ancestor::td/preceding-sibling::th[.='LQM:']] 
|//a[ancestor::td/preceding-sibling::th[.='LBR:']] 
|//a[ancestor::td/preceding-sibling::th[.='RTT:']] 

我加入了<table>標籤在你的輸入和應用以下XSL轉換測試這:

<a href="docs/lqm.html"><b>Intro</b></a> 
<a href="P/P79/">79</a> 
<a href="P/P80/">80</a> 
<a href="P/P81/">81</a> 
<a href="P/P82/">82</a> 

當然,如果您使用XSL,那麼您可能會發現t他的建築更具可讀性:

<xsl:for-each select="//a"> 
    <xsl:variable name="header" select="ancestor::td/preceding-sibling::th"/> 

    <xsl:if test="$header='LQM:' or $header = 'LBR:' or $header = 'RTT:'"> 
     <xsl:text> 
     </xsl:text> 
     <xsl:copy-of select="."/> 

    </xsl:if> 
</xsl:for-each> 
+0

謝謝!這當然有用,但這真的是最好的方法嗎? – duckworthd

+0

如果您使用的是XPath 2.0,請參閱[本答案](http://stackoverflow.com/a/356777/4525)。否則,是的,我認爲這是最好的方法。 – harpo

+0

另請注意,我用比我的第一個版本更短的版本進行了更新。 – harpo