2011-07-24 2 views
2

Какое выражение следует использовать для поиска всех узлов td после того, как текст Foo или Bar и остановка перед следующим <td colspan="4"> с неизвестным текстом. Благодарю.Найти узлы до состояния с использованием XPath

<td colspan="4">Foo || Bar</td> 
<td rowspan="4">TEXT1</td> 
<td valign="top">TEXT2</td> 
<td valign="top">TEXT3</td> 
... 
<td colspan="4">VARIABLE</td> 
... 

UPDATE:

use strict; 
use warnings; 
use autodie; 
use utf8; 
use WWW::Mechanize; 
use HTML::TreeBuilder::XPath; 

my $url = 'www.perl.org'; 

my $mech = WWW::Mechanize->new; 
$mech->agent_alias('Windows Mozilla'); 
$mech->get($url); 

my $tree= HTML::TreeBuilder::XPath->new; 

$tree->parse($mech->content); 

for my $nodes ($tree->findnodes('//td[ 
          preceding-sibling::td 
          [contains(., "Foo") or contains(., "Bar")] 
          and following-sibling::td[@colspan="4"] 
          ]')) { 

    print $nodes->as_text; 

} 

ответ

1

Вы можете использовать XPath:

//td[ 
     preceding-sibling::td 
      [contains(., 'Foo') or contains(., 'Bar')] 
     and following-sibling::td[@colspan = 4] 
] 

Он вернется:

<td rowspan="4">TEXT1</td> 
<td valign="top">TEXT2</td> 
<td valign="top">TEXT3</td> 
+0

Спасибо. Если это выражение работает в HTML :: TreeBuilder :: XPath, потому что по какой-то причине я не получаю результатов. – thebourneid

+0

@thebourneid, я понятия не имею, работает ли он с HTML: TreeBuilder :: XPath'. Я предоставляю только действующий стандартный XPath. –

+0

Хорошо. Я сделаю еще несколько тестов. Вы очень помогли. Благодарю. – thebourneid

0

Ну с XPath 2.0 и XQuery 1.0 существуют операторы << и >>, которые помогают выразить условия, как у вас есть, например, с XQuery вы можете красиво написать

let $tr := <tr> 
<td colspan="4">Foo || Bar</td> 
<td rowspan="4">TEXT1</td> 
<td valign="top">TEXT2</td> 
<td valign="top">TEXT3</td> 
..... 
<td colspan="4">VARIABLE</td> 
</tr> 
let $td1 := $tr/td[contains(., 'Foo') or contains(., 'Bar')][1] 
let $td2 := $td1/following-sibling::td[@colspan = 4][1] 
return $tr/td[. >> $td1 and . << $td2] 

найти 'td элементы «между» этими двумя другими td элементами.

Очевидно, что с помощью XPath 2.0 вы не Выпускаемое и вернуться, так что вам нужно будет стараться придерживаться все в одном выражении:

$tr/td[. >> $tr/td[contains(., 'Foo') or contains(., 'Bar')][1] and . << $tr/td[contains(., 'Foo') or contains(., 'Bar')][1]/following-sibling::td[@colspan = 4][1]] 

где $tr является контекстный узел.

Смежные вопросы