Xquery在html中提取文本

时间:2010-06-23 10:18:08

标签: xpath xquery

我正在从html文档中提取文本并存储在数据库中。我正在使用webharvest工具来提取内容。但是我有点卡在某一点上。在webharvest内部,我使用XQuery表达式来提取数据。我正在解析的html文档如下:

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

我需要从上面的html脚本中提取“Hello world”文本。

我尝试以这种方式提取文本:

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

然而,我总是得到的是“HELLOWORLD”,而不是“Hello world”。

有没有办法提取“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>

我想提取hwe2和hw3之间的文本Hello world 2。我不想使用text()[3]但有一些方法可以在/ [[name ='hw2']和/ [[name ='hw3']之间提取文本。

3 个答案:

答案 0 :(得分:6)

您的xpath正在选择a节点的文本,而不是td节点的文本:

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

将其更改为:

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

更新(在评论和更新问题之后):

此xpath选择$item中具有a标记的第二个文本节点,其中name属性设置为hw

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

答案 1 :(得分:3)

  

我不想使用text()[3]但是   有什么方法可以提取出来   在/a[@name='hw2'] and /a[@name='hw3']之间输出短信。

如果两个<a>元素之间只有一个文本节点,那么以下内容非常简单:

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

如果两个元素之间有多个文本节点,则需要表示第一个元素后面的所有文本节点与第二个元素前面的所有文本节点的交集。两个节点集(也称为Kaysian交集方法)的交集公式为:

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

因此,只需将上述表达式$ns1替换为:

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

$ns2

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

最后,如果你真的有XQuery(或XPath 2),那么这只是:

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

intersect

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

答案 2 :(得分: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”元素的第一个节点。