2014-10-10 372 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; 
相關問題