2012-08-05 43 views
1

我有一個我想用C#和XPath查詢的HTML文檔。我正在尋找的是XPath表達式 - 而不是XSLT,C#,PHP或任何其他語言特定的代碼示例。任何幫助將不勝感激,但XPath表達式是我需要的:)。使用XPath查詢HTML文檔

<tr> 
    <td> 
    <p> 
     <span>text</span> 
    </p> 
    </td> 
    <td> 
    <p> 
     <span>text</span> 
    </p> 
    </td> 
</tr> 
<tr> 
    <td> 
    <p> 
     <span>This text is static and will never change</span> 
    </p> 
    </td> 
    <td> 
    <p> 
     <span>Bla bla bla .... more bla bla bla</span> 
    </p> 
    </td> 
</tr> 
<tr> 
    <td> 
    <p> 
     <span>text</span> 
    </p> 
    </td> 
    <td> 
    <p> 
     <span>text</span> 
    </p> 
    </td> 
</tr> 

我正在查找的XPath表達式將提取當前由字符串實例「Bla bla bla ...... more bla bla bla」表示的文本。本文將從HTML文檔到HTML文檔有所不同,但一個字符串始終是相同的。在這種情況下,該字符串被表示爲「這個文本是靜態的並且永遠不會改變」。

「這個文本是靜態的,永遠不會改變」和「Bla bla bla ....更多bla bla bla」當然不是真正的字符串 - 我將它們替換,因爲它們是域特定的,與問題無關並且它們揭示了不能顯示的敏感數據!

再次,任何幫助將不勝感激。謝謝。

+0

使用的是什麼語言 - PHP? JavaScript的? HTML本身不能做到這一點。請編輯問題以標記語言。 – Utkanos 2012-08-05 21:59:24

+1

@Utkanos:XPath表達式與語言無關。 – 2012-08-05 22:00:28

+0

我意識到這一點,但他/她將用某種語言來實現它。他/她被重新標記爲C#。 – Utkanos 2012-08-05 22:04:08

回答

2

使用

/*/tr[2]/td[2]/p/span/text() 

當這個XPath表達式與下面的XML文檔(通過轉動提供不良HTML成簡潔(wellformed)XML文檔而獲得)來評價:

<table> 
    <tr> 
     <td> 
      <p> 
       <span>text</span> 
      </p> 
     </td> 
     <td> 
      <p> 
       <span>text</span> 
      </p> 
     </td> 
    </tr> 
    <tr> 
     <td> 
      <p> 
       <span>Some text</span> 
      </p> 
     </td> 
     <td> 
      <p> 
       <span>text to extract</span> 
      </p> 
     </td> 
    </tr> 
    <tr> 
     <td> 
      <p> 
       <span>text</span> 
      </p> 
     </td> 
     <td> 
      <p> 
       <span>text</span> 
      </p> 
     </td> 
    </tr> 
</table> 

的根據需要選擇值爲"text to extract"的文本節點

XSLT - 基於驗證

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    "<xsl:copy-of select="/*/tr[2]/td[2]/p/span/text()"/>" 
</xsl:template> 
</xsl:stylesheet> 

當該變換是在相同的XML文檔(上文),XPath表達式求值和該評價的結果施加被複制到輸出

"text to extract" 

或者,如果你知道的文字,但要選擇包含的一個元素(比如td),然後使用

//text()[. = 'text to extract']/ancestor::td[1] 

再次用基於XSLT的驗證:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy-of select= 
     "//text()[. = 'text to extract']/ancestor::td[1]"/> 
</xsl:template> 
</xsl:stylesheet> 

結果現在是

<td> 
    <p> 
     <span>text to extract</span> 
    </p> 
</td> 

又一猜

如果你想找到最接近文本節點,然後用:

//text()[. = 'text to extract']/preceding::text()[1] 

XSLT - 基於驗證:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    "<xsl:copy-of select= 
     "//text()[. = 'text to extract']/preceding::text()[1]"/>" 
</xsl:template> 
</xsl:stylesheet> 

結果

"Some text" 

更新

由OP,和他的新解釋,XPath表達式,他正在尋找最新的更新後:

//text()[. = 'This text is static and will never change']/following::text()[1] 

這將選擇與字符串值的文本節點:

"Bla bla bla .... more bla bla bla" 
+0

不幸的是''[2]'在這裏太具體了;它需要錨定在「某些文本」上,而不是絕對的位置。 – 2012-08-05 22:09:49

+0

正如Ignacio Vazquez-Abrahams所說......這只是一個HTML樣本,以顯示結構。在兩個有趣的之前或之後可能有一千行。雖然結構當然是相同的。 – 2012-08-05 22:12:13

+0

@ IgnacioVazquez-Abrams,似乎你和我對這個問題有不同的理解。根據你的理解,我將編輯答案並提供第二個表達。 – 2012-08-05 22:13:52