Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 按第一个子元素的名称选择HTML元素_Perl - Fatal编程技术网

Perl 按第一个子元素的名称选择HTML元素

Perl 按第一个子元素的名称选择HTML元素,perl,Perl,如果所有元素都有子元素,那么我需要找到id属性的值 例如,给定以下HTML <div id="a1"> <span> xa1 </span> </div> <div id="a2"> <p>...</p> <span> xa2 </span> </div> <div id="a3">

如果所有
元素都有
子元素,那么我需要找到
id
属性的值

例如,给定以下HTML

<div id="a1">                 <span> xa1 </span>       </div>
<div id="a2"> <p>...</p>      <span> xa2 </span>       </div>
<div id="a3">            <p>  <span> xa3 </span> </p>  </div>
<div id="a4"> <p>...</p>                             </div>

<div id="b1"> </div>          <span> xb1 </span>
<div id="b2"> </div> <p>      <span> xb1 </span> </p>
<div id="b3"> </div> <p>.</p> <span> xb3 </span>

不幸的是,
Mojo::DOM
不支持XPath表达式和CSS,因为前者是非常自然的表达式

<>你可能想考虑切换到。代码如下所示。它使用XPath表达式

//div[*][local-name(*[1])="span"]/@id
它要求文档中至少有一个子元素且第一个子元素的本地名称为
span
的任何
div
元素的
id
属性

use strict;
use warnings;
use 5.014;

use HTML::TreeBuilder::XPath;

my $tree = do {
   local $/;
   HTML::TreeBuilder::XPath->new_from_content(<DATA>);
};

say for $tree->findvalues('//div[*][local-name(*[1])="span"]/@id');

__DATA__
<html><body>
<div id="a1">                 <span> xa1 </span>       </div>
<div id="a2"> <p>...</p>      <span> xa2 </span>       </div>
<div id="a3">            <p>  <span> xa3 </span> </p>  </div>
<div id="a4"> <p>...</p>                             </div>

<div id="b1"> </div>          <span> xb1 </span>
<div id="b2"> </div> <p>      <span> xb1 </span> </p>
<div id="b3"> </div> <p>.</p> <span> xb3 </span>

<p id="p1">                <span> xp1 </span>       </p>
<p id="p2"> <p>...</p>     <span> xp2 </span>       </p>
<p id="p3">            <p> <span> xp3 </span> </p>  </p>
<p id="p4"> <p>...</p>                              </p>
</body></html>

您可以使用css样式选择器和Mojo::DOM的方法以稍微迂回的方式获得所需的元素:

或者,如果您知道这只是您想要的第一个这样的div,那么下面的方法就可以了:

say "id: " . $dom->at('div > span:first-child')->parent->attr('id');
或者:

my @spans = $div->find('div > span:first-child')->each;
say $div->attr('id') if (@spans == 1);
或者这个:

my @kids = $div->children;
say $div->attr('id') if @kids and $kids[0]->type eq 'span';

Thanx,但它也会打印
a1
a2
。正如我在问题中所说,我只想要
a1
。@cajwine:我道歉。我只是在重读问题时遇到了这个问题。我更喜欢Mojo::DOM,因为它更接近jquery,所以我不需要再学习另一种格式。@marneborn:这很公平。实际上是在CSS和XPath之间进行选择,因为CSS3的选择主要是个人偏好,但最好在
Mojo::DOM
YES中包含这两种选择!我有点忽略了第一个孩子和第n个孩子。。塔克斯。接受这一点,因为这是我已经知道的Mojo::DOM解决方案。
id: a1
say "id: " . $dom->at('div > span:first-child')->parent->attr('id');
my @spans = $div->find('div > span:first-child')->each;
say $div->attr('id') if (@spans == 1);
my @kids = $div->children;
say $div->attr('id') if @kids and $kids[0]->type eq 'span';