2010-01-13 7 views
4

중첩 된 테이블을 포함하지 않고 내 현재 노드 아래의 모든 테이블 을 찾으려고합니다. 나는이있는 경우 즉, 나는 "아니오" "예"가 아닌 찾으려면 : XPath는 1.0에서이 작업을 수행 할 수있는 쉬운 방법XPath 1.0과의 차이점 설정 - .table/ttable없이 .// 테이블을 얻으려면 어떻게해야합니까?

<table> <!-- outer table - no --> 
    <tr><td> 
    <div> <!-- *** context node *** --> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
    </div> 
    </td></tr> 
</table> 

있습니까? (2.0, 그것은 .//table except .//table//table 것,하지만 옵션으로 2.0이 없습니다.)

편집 :하십시오, 지금까지 현재 컨텍스트 노드의 생각을 존중하지 않는 답변. 나는 테이블의 첫 번째 층이 얼마나 떨어져 있는지 (그리고 다를지도 모른다), 내가 다른 테이블 (또는 두세개)에 있을지 여부를 알지 못한다.

문자 그대로, 나는 XPath는 2.0 .//table except .//table//table가 될 것을 원하지만, 난 단지 XPath는 1

+0

하나의 컨텍스트를 여러 번 사용해야하기 때문에 하나의 XPath 1.0 만 작성할 수는 없으며 허용되지 않습니다. 두 개의 XPath, 한 개의 XPath를 사용하여 변수의 값을 가져오고 두 번째 XPath를 사용하여 필요한 테이블을 가져올 수 있습니까? – Gaim

+0

어떤 이유에서 이것을 CW로 만들었습니까? CW에 대한 후보가 아니라 올바른 대답을 갖는 매우 까다로운 질문입니다. – AnthonyWJones

+0

"CW"란 무엇입니까? 그리고 당신은 "당신"으로 누구를 언급하고 있습니까? 나를? 어떻게 이것을 "CW"로 만들었습니까? :) –

답변

0

여기와 다른 곳을 조사한 결과, 대답은 것 같다 "당신은 할 수 없습니다, 우리는 XPath는 2.0이 이유입니다." 오 잘.

0

당신이 아이 :: 테이블 일명 테이블

#!/usr/bin/perl -- 
use strict; 
use warnings; 

use HTML::TreeBuilder; 
{ 
    my $tree = HTML::TreeBuilder->new(); 

    $tree->parse(<<'__HTML__'); 
<table> <!-- outer table - no --> 
    <tr><td> 
    <div> <!-- *** context node *** --> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
    </div> 
    </td></tr> 
</table> 
__HTML__ 

    sub HTML::Element::addressx { 
    return join(
     '/', 
     '/', # // ROOT 
     reverse( # so it starts at the top 
     map { 
      my $n = $_->pindex() || '0'; 
      my $t = $_->tag; 
      $t . '['. $n .']' 
      }   # so that root's undef -> '0' 
      $_[0], # self and... 
     $_[0]->lineage 
    ) 
    ); 
    } ## end sub HTML::Element::addressx 

    for my $td ($tree->look_down(_tag => qr/div|table/i)) { 
    print $td->addressx, "\n"; 
    } 
    $tree->delete; 
    undef $tree; 
} 
__END__ 
//html[0]/body[1]/table[0] 
//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0] 
//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]/table[0] 
//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]/table[0]/tr[0]/td[0]/table[0] 
//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]/table[1] 
//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]/table[1]/tr[0]/td[0]/table[0] 

와 두 번째 부분

을하려는 생각을 가지고
#!/usr/bin/perl -- 

use strict; 
use warnings; 

use HTML::TreeBuilder::XPath; 

my $tree = HTML::TreeBuilder::XPath->new; 
$tree->parse_content(<<'__HTML__'); 
<table> <!-- outer table - no --> 
    <tr><td> 
    <div> <!-- *** context node *** --> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
     <table> <!-- yes --> 
     <tr><td> 
      <table> ... </table> <!-- no --> 
     </td></tr> 
     </table> 
    </div> 
    </td></tr> 
</table> 
__HTML__ 



#~ for my $result ($tree->findnodes(q{//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]})) { 
for my $result ($tree->findnodes(q{/html/body/table/tr/td/div})) { 
    print $result->as_HTML,"\n\n"; 
    for my $table($result->findnodes(q{table})){ ## child::table 
     print "$table\n"; 
     print $table->as_HTML,"\n\n\n"; 
    } 

} 

__END__ 
<div><table><tr><td><table><tr><td> ... </td></tr></table></td></tr></table><table><tr><td><table><tr><td> ... </td></tr></table></td></tr></table></div> 


HTML::Element=HASH(0xc6c964) 
<table><tr><td><table><tr><td> ... </td></tr></table></td></tr></table> 



HTML::Element=HASH(0xc6cbf4) 
<table><tr><td><table><tr><td> ... </td></tr></table></td></tr></table> 
+0

아니요, 컨텍스트 노드를 존중하지 않습니다. –

0

글쎄, 내가 알고있는 경우 CONTENT_LIST는 해결할 수 :

my $table_one = $tree->findnodes('/html//table')->[1]; 

for ($table_one->content_list) { 
    last if $_->exists('table'); 
    print $_->as_text; 
} 

:

+0

아니요. 컨텍스트 노드를 존중하지 않습니다. –

0

.//table[not(.//table)]은? 간결하게해서 미안 해요, 제 전화로 왔습니다.

+0

아니, 그 테이블이없는 모든 테이블을 찾습니다. 나는 테이블 안에없는 모든 테이블을 원합니다. –

+0

OK, 어떻습니까 .//table[not (ancestor:: table)]? 그것은 비효율적 일 가능성이 매우 높습니다. eXist와 같이 인덱스를 지원하지 않는 한 비효율적입니다. –

+0

Nope. 테이블에없는 한 모든 테이블을 찾습니다. 그러나 우리의 컨텍스트 노드가 이미 테이블 내에 있다면 어떻게 될지 생각해보십시오. 아무것도 찾지 못할거야. 아니, 대답이 아니야. –

0

내가 컨텍스트 노드가 중첩 된 조건에서 평가 될 수 있지만, 당신이 필요로하는 것은이 같은 것입니다 방법을 모르는 : 만 컨텍스트 노드를 참조 할 수있는 기능

descendant::table[not(ancestor::table[ancestor::div])] 

대신 div

편집 : 당신은 컨텍스트 노드에 대한 변수를 설정하면

<xsl:variable name="contextNode" select="." /> 

다음은 XPATH 술어에서 참조 할 수 있습니다 :

descendant::table[not(ancestor::table[ancestor::*[generate-id(.)=generate-id($contextNode)]])] 
+0

그래도 여전히 작동하지 않습니다. 왜냐하면 어떤 div 내에있는 테이블에있는 테이블도 배제 할 것이기 때문입니다. :) 다시 컨텍스트를 존중하지 않습니다. –

+0

내 대답이 업데이트되었습니다. 그것은 순수한 XPATH가 아니지만 XPATH 1.0 (및 XSLT 1.0) 솔루션입니다. –

+0

네, 여기에 XSLT가 없습니다. 그래서 그것도 그렇게하지 않습니다. {한숨}. –

관련 문제