У меня есть эта таблица на веб-сайте. Возьмите таблицу xpath в php. Я хочу взять информацию из таблицы и поставить базу на атрибуты определенных продуктов в OpenCart.
<table border="0" width="100%" style="float:left">
<tbody>
<tr>
<td rowspan="2" class="gr">Dimensiuni</td>
<td class="c3">Dimensiuni (W x D x H mm):</td>
<td class="c4">138.5 x 70.9 x 8.9 mm</td>
</tr>
<tr>
<td class="c3">Greutate (g):</td>
<td class="c4">143 g</td>
</tr>
<tr>
<td rowspan="3" class="gr">Display</td>
<td class="c3">Dimensiune Display (inches):</td>
<td class="c4">5.2</td>
</tr>
<tr>
<td class="c3">Rezolutie (pixeli):</td>
<td class="c4">1080 x 1920 pixels, 5.2 inches (~424 ppi pixel density)</td>
</tr>
<tr>
<td class="c3">Culori:</td>
<td class="c4">16M colors</td>
</tr></tbody>
</table>
Я хочу получить информацию из таблицы и сформировать массив вида
Array(
[Dimensiuni] => array(
[Dimensiuni (W x D x H mm)] => 138.5 x 70.9 x 8.9 mm,
[Greutate (g)] => 143 g
)
[Display] => array(
[Dimensiune Display (inches)] => 5.2,
[Rezolutie (pixeli)] => 1080 x 1920 pixels, 5.2 inches (~424 ppi pixel density),
.
.
.
)
)
Я пришел сюда и вот я застрял.
$attributeQuery = $xpath->query("//table[@border='0'][@width='100%'][@style='float:left']//td[@class='gr']");
if($attributeQuery->length > 0){
foreach($attributeQuery as $attribute){
$attr[$attribute->nodeValue] = array();
}
}
Эта таблица является динамической, я хочу немного общего.
Не уверен, что это сработает для вас, но вы можете попробовать изменить
foreach($attributeQuery as $attribute){
$attr[$attribute->nodeValue] = array();
}
в
foreach ($attributeQuery->attributes as $attr) {
$array['@'.$attr->localName] = $attr->nodeValue;
}
Вы в основном ищете <td>
элемент, который имеет rowspan
атрибут, чтобы получить раздел.
Это может быть достигнуто путем итерации по строкам и установки раздела, только если он доступен в текущей строке, а затем сохранения его до тех пор, пока он снова не станет доступен:
// initialize section
$section = null;
foreach ($table->getElementsByTagName('tr') as $row) {
// sec section only when found
$sectionTd = $xpath->evaluate('self::tr/td[@rowspan]', $row);
if ($sectionTd->length) {
$section = $sectionTd->item(0)->nodeValue;
}
...
printf("%s - %s %s\n", $section, $name, $value);
}
Примерный вывод:
Dimensiuni - Dimensiuni (W x D x H mm): 138.5 x 70.9 x 8.9 mm
Dimensiuni - Greutate (g): 143 g
Display - Dimensiune Display (inches): 5.2
Display - Rezolutie (pixeli): 1080 x 1920 pixels, 5.2 inches (~424 ppi pixel density)
Display - Culori: 16M colors
Другой альтернативой является прямое использование xpath для поиска этого <td>
элемент с rowspan и для противоположного случая, когда он не найден, взять первый предыдущий, который имеет его:
(
self::tr[td/@rowspan]
|self::tr[not(td/@rowspan)]/preceding-sibling::tr[td/@rowspan][1]
)/td
Это действительно для инициализации $section
переменная перед циклом, поэтому она более автономна:
foreach ($table->getElementsByTagName('tr') as $row) {
$section = $xpath->evaluate(
'string((self::tr[td/@rowspan]|self::tr[not(td/@rowspan)]/preceding-sibling::tr[td/@rowspan][1])/td)', $row
);
...
Это снова дает тот же результат:
Dimensiuni - Dimensiuni (W x D x H mm): 138.5 x 70.9 x 8.9 mm
Dimensiuni - Greutate (g): 143 g
Display - Dimensiune Display (inches): 5.2
Display - Rezolutie (pixeli): 1080 x 1920 pixels, 5.2 inches (~424 ppi pixel density)
Display - Culori: 16M colors
Вот полный пример кода:
<?php
$html
= <<<HTML
<table border="0" width="100%" style="float:left">
<tbody>
<tr>
<td rowspan="2" class="gr">Dimensiuni</td>
<td class="c3">Dimensiuni (W x D x H mm):</td>
<td class="c4">138.5 x 70.9 x 8.9 mm</td>
</tr>
<tr>
<td class="c3">Greutate (g):</td>
<td class="c4">143 g</td>
</tr>
<tr>
<td rowspan="3" class="gr">Display</td>
<td class="c3">Dimensiune Display (inches):</td>
<td class="c4">5.2</td>
</tr>
<tr>
<td class="c3">Rezolutie (pixeli):</td>
<td class="c4">1080 x 1920 pixels, 5.2 inches (~424 ppi pixel density)</td>
</tr>
<tr>
<td class="c3">Culori:</td>
<td class="c4">16M colors</td>
</tr>
</tbody>
</table>
HTML;
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);/** @var DOMElement $table */
$table = $doc->getElementsByTagName('table')->item(0);
foreach ($table->getElementsByTagName('tr') as $row) {
$section = $xpath->evaluate(
'string((self::tr[td/@rowspan]|self::tr[not(td/@rowspan)]/preceding-sibling::tr[td/@rowspan][1])/td)', $row
);
$name = $xpath->evaluate('string(./td[@class="c3"])', $row);
$value = $xpath->evaluate('string(./td[@class="c4"])', $row);
printf("%s - %s %s\n", $section, $name, $value);
}
Я оставляю создание массива в качестве небольшого упражнения, так как раздел теперь известен в итерации, это должно быть намного проще.