2012-11-08 53 views
0

請參閱底部的編輯:最高效的遍歷方法

我正在使用XPath從網站上刮取一些數據。林想知道我是否可能使用了太多foreach() loops,並且可能會以更簡單的方式遍歷層次結構。我覺得我可能會使用太多的查詢,並且可能會有更好的方法使用一個

層次結構看起來像這樣。

<ul class='item-list'> 
    <li class='item' id='12345'> 
     <div class='this-section'> 
      <a href='http://www.thissite.com'> 
       <img src='http://www.thisimage.com/image.png' attribute_one='4567' attribute-two='some-words' /> 

     </div> 
     <small class='sale-count'>Some Number</small> 
    </li> 
    <li class='item' id='34567'> 
    <li class='item' id='48359'> 
    <li class='item' id='43289'> 
</ul> 

所以我做了以下內容:

$dom = new DOMDocument; 
@$dom->loadHTMLFile($file); 
$xpath = new DOMXPath($dom); 

$list = $xpath->query("//ul[@class='item-list']/li"); 

foreach($list as $list_item) 
{ 
$item['item_id'][] = $list_item->getAttribute('id'); 

$links = $xpath->query("div[@class='this-section']//a[contains(@href, 'item')]", $list_item); 

foreach($links as $address) 
{ 
    $href = $address->getAttribute('href'); 
    $item['link'][] = substr($href, 0, strpos($href, '?')); 
} 

$other_data = $xpath->query("div[@class='this-section']//*[@attribute-one]", $list_item); 

foreach($other_data as $element) 
{ 
    $item['cost'][] = $element->getAttribute('atribute-one'); 
    $item['category'][] = $element->getAttribute('attribute-two'); 
    $item['name'][] = $element->getAttribute('attribute-three');   

} 

$sales = $xpath->query(".//small[@class='sale-count']", $list_item); 

foreach($sales as $sale) 
    $item['sale'][] = substr($sale->textContent, 0, strpos($sale->textContent, ' ')); 
} 

我需要不斷地重新查詢工作我倒層次,或者是有一個更簡單的實現這種方式?

編輯 所以看來我確實使用了太多的foreach循環。對於每一個我拿出來的,我都省了一大筆記憶。所以我的問題變成了。

一個我有父元素(在這種情況下<li>),沒有一種方法來挑選元素和屬性,而無需重新查詢和循環遍歷結果嗎?我需要消除儘可能多的這些xpath子查詢,並儘可能地去除foreach循環。

+0

看起來相當整齊我.. :) – Ben

+0

雖然你可能可以循環通過'$ image->屬性',如果你想*所有*的屬性.. – Ben

+0

啊好吧好點,我試試! – djt

回答

0

當然,你可以使用DOMElement::getElementsByTagName()代替:對於這

$images = $list_item->getElementsByTagName('img'); 

更有效,你必須對它進行基準測試。您可以在相對XPath查詢或<li>的節點樹的前序遍歷之間進行速度比較。

+0

好的,那是真的。當我進行性能測試時,我會把它放在後面的口袋裏! – djt