2015-09-18 2 views
1

У меня есть простое приложение PHP, которое анализирует содержимое html и извлекает данные из td, который соответствует определенному запросу.Анализ HTML-таблицы на основе соседнего тега заголовка с использованием DOMDocument и DOMXPath

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). Таблица «голая». Нет идентификатора, нет класса или какой-либо идентификации. Единственное, что их идентифицирует, это тег h3. Скажем, я предоставляю запрос, который задает h3 ($ q2 = HELLO WORLD), можно ли извлекать данные только из первой таблицы?

ответ

1

Вы хотите использовать ось предшествующего-родственную и [1] позиционного предикат (или как там оно официально называется), и посмотреть на текстовом содержании h3 элементов, чтобы найти какие h3 элемента является один прямо перед table вы хотите ; поэтому, я думаю, это:

//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"]]