2014-10-10 370 views
0

我的布局是这样的:如何使用dom xpath选择具有相同标记的第二个元素?

<div class="fly"> 
    <img src="a.png" class="badge"> 
    <img class="aye" data-original="b.png" width="130" height="253" />   
     <div class="to"> 
       <h4>Fly To The Moon</h4> 
        <div class="clearfix"> 
         <div class="the"> 
          <h4>**Wow**</h4> 
         </div> 
         <div class="moon"> 
          <h4>**Great**</h4>      
         </div> 
        </div> 
      </div> 
</div> 

首先,我得到的查询从XPath的:

$a = $xpath->query("//div[@class='fly']""); //to get all elements in class fly  
foreach ($a as $p) { 
    $t = $p->getElementsByTagName('img'); 
    echo ($t->item(0)->getAttributes('data-original')); 
} 

当我运行的代码,它会产生0的结果。在我追踪之后,我发现<img class="badge">首先被处理。我想问一下从<img class="aye">,我怎么能得到数据的原始值,并获得价值“”和“”从<h4>标签?

谢谢

回答

1

Alernatively,你可以使用另一个XPath查询上对当前的代码添加。

获取属性,使用->getAttribute()

$dom = new DOMDocument(); 
$dom->loadHTML($markup); 
$xpath = new DOMXpath($dom); 
$parent_div = $xpath->query("//div[@class='fly']"); //to get all elements in class fly 

foreach($parent_div as $div) { 
    $aye = $xpath->query('./img[@class="aye"]', $div)->item(0)->getAttribute('data-original'); 
    echo $aye . '<br/>'; // get the data-original 
    $others = $xpath->query('./div[@class="to"]/div[@class="clearfix"]', $div)->item(0); 
    foreach($xpath->query('./div/h4', $others) as $node) { 
     echo $node->nodeValue . '<br/>'; // echo the two h4 values 
    } 
    echo '<hr/>'; 
} 

Sample Output

+0

鬼,你知道如何从jQuery的AJAX解析数据恢复?它隐藏在html标签中。谢谢。 – 2014-10-10 11:43:28

+0

@ AndrewB.O。你什么意思不起作用?你看过演示了吗?并且关于那个隐藏的输入,没有一个ajax渲染的动态值不能用这种方式解析,你需要使用phantomjs或者selenium来做这个 – Ghost 2014-10-10 11:48:43

+0

是的。我已经看过演示,但是当我将你的代码应用于我的案例(通过布局进行说明)时,会给出不同的结果。所以,我改变了一下你的代码。很多人都很感谢你的帮助:) PhantomJS在客户端运行,我在服务器端解析文档。我如何使用它? – 2014-10-11 06:44:16

1

谢谢您的代码!

我尝试的代码,但它失败了,我不知道为什么。所以,我改变了一些你的代码,它的工作原理!

$dom = new DOMDocument(); 
$dom->loadHTML($markup); 
$xpath = new DOMXpath($dom); 
$parent_div = $xpath->query("//div[@class='fly']"); //to get all elements in class fly 

foreach($parent_div as $div) { 
    $aye = $xpath->query('**descendant::**img[@class="aye"]', $div)->item(0)->getAttribute('data-original'); 
    echo $aye . '<br/>'; // get the data-original 
    $others = $xpath->query('**descendant::**div[@class="to"]/div[@class="clearfix"]', $div)->item(0); 
    foreach($xpath->query('.//div/h4', $others) as $node) { 
     echo $node->nodeValue . '<br/>'; // echo the two h4 values 
    } 
    echo '<hr/>'; 
} 

我不知道是什么./descendant之间的区别,但使用descendant我的代码工作正常。

0

给出下面的XML:

<div class="fly"> 
    <img src="a.png" class="badge"> 
    <img class="aye" data-original="b.png" width="130" height="253" />   
     <div class="to"> 
       <h4>Fly To The Moon</h4> 
        <div class="clearfix"> 
         <div class="the"> 
          <h4>**Wow**</h4> 
         </div> 
         <div class="moon"> 
          <h4>**Great**</h4>      
         </div> 
        </div> 
      </div> 
</div> 

你问:

我怎样才能从<img class="aye">得到data-original值,也从<h4>标签获得的价值 “哇” 和 “大”?

在XPath,你可以得到的值作为字符串直接:

string(//div[@class='fly']/img/@data-original) 

这是一个img标签的第一个数据,原始属性带class =“飞翔”的所有div内的字符串。

string(//div[@class='fly']//h4[not(following-sibling::*//h4)][1]) 
string(//div[@class='fly']//h4[not(following-sibling::*//h4)][2]) 

这些都是后面没有对所有div class="fly"在它自己的级别由另一<h4>标签第一和第二<h4>标签的字符串值。

这看起来有点像现在的方式站立,但随着迭代,在前面的部分将不再需要任何再快,因为XPath的话会相对的:

//div[@class='fly'] 
    string(./img/@data-original) 
    string(.//h4[not(following-sibling::*//h4)][1]) 
    string(.//h4[not(following-sibling::*//h4)][2]) 

使用XPath string(...)表达式在PHP中,您必须使用DOMXPath::evaluate()而不是DOMXPath::query()。那么这将如下所示:

$aye = $xpath->evaluate("string(//div[@class='fly']/img/@data-original)"); 
$h4_1 = $xpath->evaluate("string(//div[@class='fly']//h4[not(following-sibling::*//h4)][1])"); 
$h4_2 = $xpath->evaluate("string(//div[@class='fly']//h4[not(following-sibling::*//h4)][2])"); 

与迭代和输出的完整的例子:

// all <div> tags with class="fly" 
$divs = $xpath->evaluate("//div[@class='fly']"); 

foreach ($divs as $div) { 

    // the first data-original attribute of an <img> inside $div 
    echo $xpath->evaluate("string(./img/@data-original)", $div), "<br/>\n"; 

    // all <h4> tags anywhere inside the $div 
    $h4s = $xpath->evaluate('.//h4[not(following-sibling::*//h4)]', $div); 

    foreach ($h4s as $h4) { 
     echo $h4->nodeValue, "<br/>\n"; 
    } 
} 

如示例所示,您可以使用评估以及对节点列表,太。从所有的<h4>获得的值不再与string()标记,因为我认为可能不止两个。

Online Demo including special string output (just exemplary)

echo <<<HTML 
{$xpath->evaluate("string(//div[@class='fly']/img/@data-original)")}<br/> 
    {$xpath->evaluate("string(//div[@class='fly']//h4[not(following-sibling::*//h4)][1])")}<br/> 
    {$xpath->evaluate("string(//div[@class='fly']//h4[not(following-sibling::*//h4)][2])")}<br/> 
<hr/> 
HTML; 
相关问题