2013-12-18 66 views
2

我不能找出如何解決這個遍歷DOM查找用戶向後

<div> 
    <p id="p1"> Price is <span>$ 25</span></p> 
    <p id='p2'> But this price is $ <span id="s1">50,23</span> </p> 
    <p id='p3'> This one : $ 14540.12 dollar</p> 
</div> 

我想要做的就是找到與它價格的元素,這是它的最短路徑。 這是我的沙發。

$elements = $dom->getElementsByTagName('*'); 

foreach($elements as $child) 
{ 
    if (preg_match("/.$regex./",$child->nodeValue)){ 
     echo $child->getNodePath(). "<br />"; 

    } 
} 

這導致

/html 
/html/body 
/html/body/div 
/html/body/div/p[1] 
/html/body/div/p[1]/span 
/html/body/div/p[2] 
/html/body/div/p[2]/span 
/html/body/div/p[3] 

這些都是我想要的元素的路徑,所以在這個測試中HTML沒關係。但在真實的網頁中,這些路徑變得非常長,並且容易出錯。 我想要做的是找到與ID屬性最接近的元素,並參考。

所以一旦找到並匹配$ regex的元素,我需要沿DOM向前走,找到第一個具有ID屬性的元素,並從中創建新的較短路徑。 在上面的HTML示例中,有3個價格與$ regex匹配。價格在:

//p[@id="p1"]/span 
//p[@id="s1"] 
//p[@id="p3"] 

所以這就是我想從我的函數返回。這意味着我還需要擺脫存在的所有其他路徑,因爲它們不包含$正則表達式

對此有何幫助?

+0

我應該使用SimpleXML的呢? – harmstra

+0

因此,這將是某種預處理分析,以準備將應用的實際XSLT?有趣! –

回答

0

您可以使用XPath跟蹤包含@id屬性的第一個節點的祖先路徑,然後關閉其路徑。未清理的代碼,但這樣的事情:

// snip 
$xpath = new DomXPath($doc); 
foreach($elements as $child) 
{ 
    $textValue = ''; 
    foreach ($xpath->query('text()', $child) as $text) 
     $textValue .= $text->nodeValue; 
    if (preg_match("/.$regex./", $textValue)) { 
     $path = $child->getNodePath(); 
     $id = $xpath->query('ancestor-or-self::*[@id][1]', $child)->item(0); 
     $idpath = ''; 
     if ($id) { 
      $idpath = $id->getNodePath(); 
      $path = '//'.$id->nodeName.'[@id="'.$id->attributes->getNamedItem('id')->value.'"]'.substr($path, strlen($idpath)); 
     } 
     echo $path."\n"; 
    } 
} 

印像

/html 
/html/body 
/html/body/div 
//p[@id="p1"] 
//p[@id="p1"]/span 
//p[@id="p2"] 
//span[@id="s1"] 
//p[@id="p3"] 
+0

偉大的延斯!這工作,它的確給了我如上的輸出。現在我想刪除不必要的路徑。在這個例子中,我只需要// [@ id =「p1」]/span,// span [@ id =「s1」]和// p [@ id =「p3」]。 我該如何做到這一點? – harmstra

+0

什麼是「不必要的路徑」?無論如何,這可能更適合作爲一個新問題。 –

+0

不要眨眼這是一個新問題。 我正在尋找包含$ regex的元素的最短路徑。正如你在上面的答案中可以看到這些路徑 // p [@ id =「p1」]/span // span [@ id =「s1」] // p [@ id =「p3」 ] 所以我不需要/ html,/ html/body等。既不是/ p [@ id =「p1」],因爲正則表達式在下面的範圍內被找到(見上面的輸出) 所以在我的例子我只需要3行輸出,其餘是不必要的 – harmstra