2014-08-28 40 views
0

我使用此代碼用於獲取左側導航欄中的元素:問題具有多個屬性,而使用PHP簡單的HTML DOM

function parseInit($url) { 
    $ch = curl_init(); 
    $timeout = 0; 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);  
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 
    $data = curl_exec($ch); 
    curl_close($ch); 
    return $data; 
} 

$data = parseInit("https://www.smile-dental.de/index.php"); 
$data = preg_replace('/<(d[ldt])(|>)/smi', '<div data-type="$1"$2', $data); 
$data = preg_replace('/<\/d[ldt]>/smi', '</div>', $data); 
$html = new simple_html_dom(); 
$html = $html->load($data); 

但面對這樣的問題。
例如,如果我用這樣的語法讓元素:$html->find("div[data-type=dd].level2"),然後我得到ALL元素與數據屬性DT,DD,DL和類名LEVEL2。如果我用另一種語法:$html->find("div.level2[data-type=dd]"),然後我得到ALL元素與數據屬性DD,但與類名LEVEL1,LEVEL2和LEVEL3等。 你能解釋一下我的問題是什麼?提前致謝!

P.S .:所有DT,DL和DD元素都用正則表達式更改爲具有適當數據屬性的DIV元素,因爲此解析器不正確地計數這些元素的數量。

+0

解析DOM使用正則表達式是_not_完成,它使用DOM解析器的完成('DOMDocument'或'SimpleXMLElement'),它們使您能夠可靠地構建和操作DOM(即:替換標記等)。 – 2014-08-28 10:40:09

+0

我告訴了其他操作(不是由解析器創建)以轉換某些HTML元素。 – jekahm 2014-08-28 10:58:18

+0

是的,我要說的是,您真的應該考慮其他方法:例如,使用不同的解析器,可以處理這些標籤。正則表達式+非正則語言不會混用,這只是生活中一個令人傷心的事實 – 2014-08-28 11:01:02

回答

0

REGEXes are not made to manipulate HTML,DOM解析器......而simple_html_dom你使用可以很容易地做到這一點...

下面的代碼會做你想要就好了什麼(查看評論):

$data = parseInit("https://www.smile-dental.de/index.php"); 

// Create a DOM object 
$html = new simple_html_dom(); 
$html = $html->load($data); 

// Find all tags to replace 
$nodes = $html->find('td, dd, dl'); 

// Loop through every node and make the wanted changes 
foreach ($nodes as $key => $node) { 
    // Get the original tag's name 
    $originalTag = $node->tag; 

    // Replace it with the new tag 
    $node->tag = 'div'; 

    // Set a new attribute with the original tag's name 
    $node->{'data-type'} = $originalTag; 
} 
// Clear DOM variable 
$html->clear(); 
unset($html); 

Here's is it in action

現在,多個屬性過濾,則可以使用以下兩種方法之一:

foreach ($html->find("div.level2") as $key => $node) { 
    if ( $node->{'data-type'} == 'dt') { 
     # code... 
    } 
} 

OR(禮貌h0tw1r3):

// array containing all the filtered nodes 
$dts = array_filter($html->find('div.level2'), function($node){return $node->{'data-type'} == 'dt';}); 

請閱讀MANUAL瞭解更多詳情...

+0

謝謝! )它比正則表達式要容易得多。這種方式很好用。但是,也許你現在知道該如何處理查詢字符串,我已經在上面描述過了,哪些得到了錯誤的結果?非常感謝您的幫助! – jekahm 2014-08-28 17:37:09

+0

非常感謝! )它對我很好! – jekahm 2014-08-28 20:07:50