XPath 1.0으로 차이를 설정 - .//table//table없이 .//table을 어떻게 얻습니까?

StackOverflow https://stackoverflow.com/questions/2058705

  •  20-09-2019
  •  | 
  •  

문제

나는 모든 테이블을 찾으려고 노력하고 있습니다 내 현재 노드 아래 중첩 테이블도 포함하지 않습니다. 다시 말해서, 내가 이것을 가지고 있다면, 나는 "아니오"가 아니라 "예"를 찾고 싶습니다.

<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>

XPath 1.0 에서이 작업을 수행하는 쉬운 방법이 있습니까? (2.0에서 .//table except .//table//table,하지만 옵션으로 2.0이 없습니다.)

편집하다: 지금까지 답은 현재 컨텍스트 노드의 아이디어를 존중하지 않습니다. 테이블의 첫 번째 레이어가 얼마나 멀리 떨어져 있는지 (그리고 다를 수 있음), 다른 테이블 (또는 2 ~ 3 개) 안에 있을지 모르겠습니다.

말 그대로, 나는 무엇을 원한다 .//table except .//table//table XPath 2.0에서는 XPath 1 만 있습니다.

도움이 되었습니까?

해결책 5

여기와 다른 곳에서 그것을 조사한 후, 대답은 "당신은 할 수 없으며, 그래서 우리는 XPath 2.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>

글쎄, 내가 그것을 이해한다면, content_list는 다음을 해결할 수 있습니다.

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

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

:)

는 어때 .//table[not(.//table)]? 간결하게 죄송합니다. 전화에 있습니다.

컨텍스트 노드를 중첩 시행자에서 평가하는 방법을 모르겠지만 필요한 것은 다음과 같습니다.

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)]])]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top