§ Код класса
<?php
libxml_use_internal_errors(true);
class xpath
{
protected DOMDocument $dom;
protected DOMXPath $xpath;
public function __construct(string $content)
{
$this->dom = new DOMDocument();
if ($content == '') {
throw new Exception("Content for empty string");
}
$this->dom->loadHTML(mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'));
$this->xpath = new DOMXPath($this->dom);
$this->dom->normalizeDocument();
libxml_clear_errors();
return $this;
}
public function query($query, $what = null, mixed $where = -1)
{
$rows = [];
$result = $this->xpath->query($query);
if ($error = libxml_get_last_error()) {
throw new Exception("XQuery [" . trim($error->message) . "] for: $query");
}
if (is_integer($what)) {
[$where, $what] = [$what, null];
}
if ($result->length === 0) {
libxml_clear_errors();
return [];
}
foreach ($result as $n => $item)
{
$row = [
'@' => $item,
'$' => $item->nodeValue,
'#' => '',
];
$dom = new DOMDocument();
if (is_object($item->attributes)) {
foreach ((object)$item->attributes as $ds) {
$row[$ds->nodeName] = $ds->nodeValue;
}
}
try {
$dom->appendChild($dom->importNode($item, true));
$row['#'] = preg_replace('~(^<[^>]*>|</[^>]*>$)~', '', trim(html_entity_decode($dom->saveHTML())));
} catch (Exception) {
$row['#'] = '';
}
unset($dom);
if ($what !== null) {
$row = $row[$what] ?? null;
}
if ($where === $n) {
$rows = $row;
break;
} else {
$rows[] = $row;
}
}
libxml_clear_errors();
return $rows;
}
}