2010-06-23 96 views
3

我正在從HTML文檔中提取文本並存儲在數據庫中。我正在使用webharvest工具來提取內容。不過,我有點卡住了。 webarvest內部我使用XQuery表達式來提取數據。那我解析HTML文件如下:Xquery在HTML中提取文本

   <td><a name="hw">HELLOWORLD</a>Hello world</td> 

我需要提取從上面的HTML腳本「Hello World」文本。

我試圖以這種方式提取文本:

 $hw :=data($item//a[@name='hw']/text()) 

但是我始終得到的是「HelloWorld」的,而不是「世界,你好」。

有沒有辦法提取「Hello World」。請幫忙。

如果我想這樣做是這樣的:

<td> 
<a name="hw1">HELLOWORLD1</a>Hello world1 
<a name="hw2">HELLOWORLD2</a>Hello world2 
<a name="hw3">HELLOWORLD3</a>Hello world3 
</td> 

我想提取文本世界,你好2是在betweeb HW2和HW3。我不想使用text()[3],但有什麼方法可以在/ a [@ name ='hw2']和/ a [@ name ='hw3']之間提取文本。

+0

好問題(+1)。查看我的答案,找出您可能需要的解決方案。 – 2010-06-23 13:33:24

回答

6

你的XPath是選擇a節點的文本,而不是在td節點的文本:

$item//a[@name='hw']/text() 

它改成這樣:

$item[a/@name='hw']/text() 

更新(以下意見和更新以提問):

此xpath從中選擇第二個文本節點具有含name屬性設置爲hwa標籤:

$item[a/@name='hw']//text()[2] 
+0

這不是爲我工作。 FYI $項目包含了整個HTML頁面的XML – Technocrat 2010-06-23 11:26:54

+0

如果什麼HTML包含: ​​ HELLOWORLD1你好world1 HELLOWORLD2你好world2 HELLOWORLD3你好world3 我不想使用文本只提取你好world2(2) 2]。是否有指定HW1" 和前/一[@名稱=‘HW2’ – Technocrat 2010-06-23 11:34:01

+0

@Technocrat「後/ A [@名稱=提取文本」的方式 - 答案更新,下面你擴大解釋 – Oded 2010-06-23 12:17:08

0

這種處理您的擴展情況,同時讓你的屬性值來選擇,而不是位置:

let $item := 
    <td> 
    <a name="hw1">HELLOWORLD1</a>Hello world1 
    <a name="hw2">HELLOWORLD2</a>Hello world2 
    <a name="hw3">HELLOWORLD3</a>Hello world3 
    </td> 

return $item//node()[./preceding-sibling::a/@name = "hw2"][1] 

這得到的第一個節點它具有名稱屬性爲「hw2」的前同胞「a」元素。

2

我不想用文字()[3]但 是有一些方法,我可以提取 文本出來/a[@name='hw2'] and /a[@name='hw3']之間。

如果有兩個<a>元素之間只有一個文本節點,那麼下面就相當簡單:

/a[@name='hw3']/preceding::text()[1]

如果有兩個元素之間不止一個文本節點,然後您需要表示第一個元素之後的所有文本節點與第二個元素之前的所有文本節點的交集。兩個節點集(交點又名Kaysian方法)的交叉點計算公式爲:

/a[@name='hw2']/following-sibling::text()

$ns2用:

$ns1[count(.|$ns2) = count($ns2)]

所以,僅僅用替換在以上表達式$ns1

/a[@name='hw3']/preceding-sibling::text()

最後,如果你確實有XQuery(或XPath 2),那麼這很簡單:

/a[@name='hw2']/following-sibling::text() 

intersect 

    /a[@name='hw3']/preceding-sibling::text()