2015-09-18 92 views
1

我有一個簡單的PHP應用程序,用於解析html內容並從td中提取匹配特定查詢的數據。使用DOMDocument和DOMXPath解析基於附近標題標記的HTML表格

HTML代碼:

<html> 
    <h3>HELLO WORLD</h3> 
    <table> 
     <tr><td>A</td><td>A2</td></tr> 
     <tr><td>B</td><td>B2</td></tr> 
     ... 
     ... 
    </table> 
    <h3>HELLO AMERICA</h3> 
    <table> 
     <tr><td>A</td><td>A3</td></tr> 
     <tr><td>C</td><td>C2</td></tr> 
     ... 
     ... 
    </table> 
    <h3>HELLO TEXAS</h3> 
    <table> 
     <tr><td>D</td><td>D2</td></tr> 
     <tr><td>E</td><td>E2</td></tr> 
     ... 
     ... 
    </table> 
<html> 

PHP代碼解析表

$content = file_get_contents($html_string); 
$dom = new DOMDocument(); 
@$dom->loadHTML($content); 
$xpath = new DOMXPath($dom); 
$query = "//tr/td[position()=1 and normalize-space(text()) = '".$q."']"; 
$entries = $xpath->query($query); 

$entryCount = $entries->length; 

if ($entryCount==1){ 
    $entry = $entries->item(0); 
    $tr = $entry->parentNode; 
    foreach ($tr->getElementsByTagName("td") as $td) { 
     $fieldnames[] = $td->textContent; 
    } 

//Return data set 
    $data[] = $fieldnames; 
    return $data; 
} 

else { 
    $data = array(); 

    for ($i=0;$i<$entryCount;$i++){ 
     $fieldnames = []; 
     $entry = $entries->item($i); 
     $tr = $entry->parentNode; 
     foreach ($tr->getElementsByTagName("td") as $td) { 
      $fieldnames[] = $td->textContent; 
     } 
     $data[] = $fieldnames; 
    } 

    return $data; 
} 

基本上,這將通過所有3個表。讓說,我發送一個查詢($ Q = A),它會返回:

$數據[0] [0] => A,$數據[0] [1] => A2
$數據[1] [0] => A,$ data [1] [1] => A3

但是,我只想要來自第一個表(A和A2)的數據。桌子是「裸體」的。沒有ID,沒有課程或任何標識。唯一標識它們的是h3標籤。比方說,我提供了一個查詢,指定h3($ q2 = HELLO WORLD),是否有可能僅從第一個表中提取數據?

回答

1

你要正確的table你想之前,使用的前同輩軸和[1]位置謂詞(或者不管它的正式名稱),並期待在h3元素的文字內容找到取其h3元素是一個;所以,我認爲,這樣的:

//table[preceding-sibling::h3[1][. = "HELLO WORLD"]] 

或者,得到的範圍內,具體的東西,這在您的示例代碼尋找,

//table[preceding-sibling::h3[1][. = "HELLO WORLD"]]/tr/td[position()=1 and normalize-space(text()) = '".$q."'] 

如果你是後來碰巧想任何其他表格,只需換出該表達式中的文本;例如,以下將在您的示例中獲得最後一個。

//table[preceding-sibling::h3[1][. = "HELLO TEXAS"]]