DOMXpath - получить атрибут href и текстовое значение элемента a
Итак, у меня есть такая HTML-строка:
<td class="name">
<a href="/blah/somename23123">Some Name</a>
</td>
<td class="name">
<a href="/blah/somename28787">Some Name2</a>
</td>
Используя XPath, я могу получить значение атрибута href, используя этот запрос Xpath:
$domXpath = new \DOMXPath($this->domPage);
$hrefs = $domXpath->query("//td[@class='name']/a/@href");
foreach($hrefs as $href) {...}
И еще проще получить текстовое значение, например:
// Xpath auto. strips any html tags so we are
// left with clean text value of a element
$domXpath = new \DOMXPath($this->domPage);
$names = $domXpath->query("//td[@class='name']/");
foreach($names as $name) {...}
Теперь мне любопытно узнать, как я могу объединить эти два запроса, чтобы получить оба значения только с одним запросом (если это что-то вроде этого даже возможно?).
Ответы
Ответ 1
Извлечь
//td[@class='name']/a
а затем вырвите текст nodeValue
и атрибут getAttribute('href')
.
Кроме того, вы можете комбинировать запросы Xpath с Operator оператора |
, чтобы вы могли использовать
//td[@class='name']/a/@href|//td[@class='name']
.
Ответ 2
Чтобы уменьшить код до одного цикла, попробуйте:
$anchors = $domXpath->query("//td[@class='name']/a");
foreach($anchors as $a)
{
print $a->nodeValue." - ".$a->getAttribute("href")."<br/>";
}
Как указано выше:) Слишком медленно..
Ответ 3
Простейший способ, evaluate
для этой задачи!
Самый простой способ получить значение - evaluate()
method:
$xp = new DOMXPath($dom);
$v = $xp->evaluate("string(/etc[1]/@stringValue)");
Примечание: важно ограничить XPath возвратом к 1 пункту (первый a
в этом случае) и отличить значение с помощью string()
или round()
и т.д.
Итак, в наборе из нескольких элементов, используя ваш код foreach
,
$names = $domXpath->query("//td[@class='name']/");
foreach($names as $contextNode) {
$text = $domXpath->evaluate("string(./a[1])",$contextNode);
$href = $domXpath->evaluate("string(./a[1]/@href)",$contextNode);
}
PS: этот пример предназначен только для иллюстрации evaluate
... Когда информация уже существует в node, используйте то, что предлагает наилучшая производительность, как методы getAttribute()
, saveXML()
и т.д. и свойства как $nodeValue
, $textContent
и т.д. предоставленный DOMNode
.
См. ответ @Gordon для этой конкретной проблемы.
Подзапрос XPath (в контексте) хорош для сложных случаев — или скомплементировать ваш код, избегая проверки hasChildNodes() + цикла для $childNodes и т.д. без значительного усиления производительности.