使用XPath 1.0设置差异-如何在没有//表//表的情况下获取//表?
我正在尝试查找当前节点下的所有表,但不包括嵌套表。换句话说,如果我有这个,我想找到“是”而不是“否”:使用XPath 1.0设置差异-如何在没有//表//表的情况下获取//表?,xpath,set-difference,Xpath,Set Difference,我正在尝试查找当前节点下的所有表,但不包括嵌套表。换句话说,如果我有这个,我想找到“是”而不是“否”: ... ... 在XPath 1.0中有什么简单的方法可以做到这一点吗?(在2.0中,它应该是//table,除了//table//table,但我没有2.0作为选项。) 编辑:请注意,到目前为止的答案不考虑当前上下文节点的概念。我不知道表的第一层到底有多远(而且可能不同),我也不知道我是否在另一个表中(或者两个或三个) 实际上,我想要的是XPath 2.0中的//table,除了
...
...
在XPath 1.0中有什么简单的方法可以做到这一点吗?(在2.0中,它应该是//table,除了//table//table
,但我没有2.0作为选项。)
编辑:请注意,到目前为止的答案不考虑当前上下文节点的概念。我不知道表的第一层到底有多远(而且可能不同),我也不知道我是否在另一个表中(或者两个或三个)
实际上,我想要的是XPath 2.0中的
//table,除了//table//table
,但我只有XPath 1。我想您想要的是child::table aka table
#!/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--
严格使用;
使用警告;
使用HTML::TreeBuilder;
{
my$tree=HTML::TreeBuilder->new();
$tree->parse(
...
...
__HTML__
子HTML::元素::地址X{
返回连接(
'/',
“/”,#//根
反向(从顶部开始)
地图{
我的$n=$\ux->pindex()||“0”;
我的$t=$\uU9->标记;
$t.['.$n.']
}#所以根是未定义的->“0”
$\u0]、\self和。。。
$\u0]>沿袭
)
);
}##结束子HTML::元素::地址X
对于我的$td($tree->look_down(_tag=>qr/div | table/i)){
打印$td->addressx,“\n”;
}
$tree->delete;
未定义$树;
}
__结束__
//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>
!/usr/bin/perl--
严格使用;
使用警告;
使用HTML::TreeBuilder::XPath;
my$tree=HTML::TreeBuilder::XPath->new;
$tree->parse_内容(
...
...
__HTML__
#~对于我的$result($tree->findnodes(q{//html[0]/body[1]/table[0]/tr[0]/td[0]/div[0]})){
对于我的$result($tree->findnodes(q{/html/body/table/tr/td/div})){
打印$result->as_HTML,“\n\n”;
对于我的$table($result->findnodes(q{table})){child::table
打印“$table\n”;
打印$table->as_HTML,“\n\n\n”;
}
}
__结束__
... ...
HTML::Element=HASH(0xc6c964)
...
HTML::Element=HASH(0xc6cbf4)
...
如果我理解的话,内容列表可以解决:
my $table_one = $tree->findnodes('/html//table')->[1];
for ( $table_one->content_list ) {
last if $_->exists('table');
print $_->as_text;
}
:)那
//table[不是(.//table)]
呢?很抱歉,我在打电话。
我不知道如何获得要在嵌套谓词中计算的上下文节点,但您需要的是如下内容:
descendant::table[not(ancestor::table[ancestor::div])]
仅能够引用上下文节点,而不是div
编辑:如果为上下文节点设置变量
<xsl:variable name="contextNode" select="." />
在这里和其他地方进行了调查之后,答案似乎是“你不能,这就是为什么我们有XPath2.0”。哦,好吧。我认为不可能只编写一个XPath 1.0,因为我需要多次使用一个上下文,这是不允许的。我可以使用两个XPath吗?一个XPath用于获取变量的值,第二个XPath用于获取所需的表?您之所以将其设置为CW是出于什么原因?这是一个相当棘手的问题,答案是正确的,不是我不是CW的候选人。什么是“CW”?你在那里称呼谁为“你”?我?我是怎么把它变成“CW”的?:)CW是“社区维基”-在最基本的层面上,它使你的问题a:更容易被其他人编辑,b:你不会从中获得任何代表点;但实际上,它倾向于暗示这是一个更基于讨论的问题。你通过单击复选框来实现这一点,并且没有“撤销”-但最终,如果你得到了一个合适的答案,这不会有太大的区别。不,这不尊重上下文节点。不,不尊重上下文节点。不,这会找到所有没有表的表。我想要所有不在表中的表。好的,怎么样//表[不(祖先::表)]这很可能是低效的,除非你做的是类似于存在的东西,它有索引来支持它。NOPE。只要不在表中,所有的表都可以找到。但是考虑一下如果我们的上下文节点已经在表内会发生什么。它什么也找不到。不,不是答案。是的,那仍然不行。因为它将排除任何div中的任何表中的任何表。:)不再考虑上下文。更新了我的答案。它不是纯XPATH,而是XPATH 1.0(和XSLT 1.0)解决方案。是的,这里没有XSLT。所以这也不行。{Sigh}。
<xsl:variable name="contextNode" select="." />
descendant::table[not(ancestor::table[ancestor::*[generate-id(.)=generate-id($contextNode)]])]