2011-08-09 16 views
3

我對XPath並不是很有經驗,但我已經嘗試了很長時間並且很多時候都沒有提出解決方案。處理兩種情況的XPath 1.0查詢

我提取XHTML是大多看起來像

<html> 
    <head></head> 
    <body> 
     <div class="preamble"> 
      <p>Some text 1</p> 
     </div> 
     <h1>Some headline</h1> 
     <p>Some other text</p> 
    </body> 
</html> 

什麼,我最感興趣的是序言中DIV,它存在於我的大多數文件的文本信息。問題是缺乏div的人,在這些情況下,我想提取body標籤下的其他文本。

在這種情況下,我想獲得「一些文本1」,但如果沒有div,我會確定「某些標題其他文本」或其他東西。

使用XPath 2.0是沒問題的,但是環境限制了我在「核心」1.0集合中的功能。

我的問題是這種行爲在一個XPath 1.0查詢中是可能的,還是我應該放棄它?

祺/馬格努斯

回答

1

試試這個XPath:

//div[@class = 'preamble'] 
    | //body/*[not(preceding-sibling::div[@class = 'preamble']) 
     and not(self::div[@class = 'preamble'])] 
1

由於XPath 1.0中沒有指定節點集排序,你要確保你的兩種情況是排斥的。

string(/html/body/div[@class='preamble'] | /html/body[not(div[@class='preamble'])]) 

如果您的XPath處理器返回文檔順序節點集,一個簡單的查詢就可以了:

string((/html/body/div[@class='preamble'] | /html/body)[last()]) 
+1

頂部一個似乎很好!謝謝:) –

+1

@Magnus Nilsson:我同意這個答案是最好的。所以,你需要*接受它 - 在這裏,這是表達感謝的既定方式。這是通過點擊最佳答案旁邊的複選標記完成的。 –

0

我想你啃老族這個XPath 1.0:

"/html/body/div[@class='preamble']//text() 
| 
/html/body[not(div/@class='preamble')]//text()" 

第一位置路徑選擇div內的所有文本節點。另一個將選擇沒有該div的所有文本節點。兩者的聯盟(|)將選擇想要的文本。

+1

謝謝!似乎工作正常。 –