DOMXpath - получает атрибут href и текстовое значение элемента - PullRequest
17 голосов
/ 25 июля 2011

Итак, у меня есть такая 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) {...}

Теперь мне интересно узнать, как я могу объединить эти два запроса, чтобы получить оба значения только одним запросом (если это что-то подобное, даже возможно)?).

Ответы [ 3 ]

20 голосов
/ 25 июля 2011

Fetch

//td[@class='name']/a

, а затем выделите текст с помощью nodeValue и атрибут с getAttribute('href').

Кроме того, вы можете комбинировать запросы Xpath с оператором объединения |, чтобы вы могли использовать

//td[@class='name']/a/@href|//td[@class='name']

.

14 голосов
/ 25 июля 2011

Чтобы свести код к одному циклу, попробуйте:

$anchors = $domXpath->query("//td[@class='name']/a");
foreach($anchors as $a)
{ 
    print $a->nodeValue." - ".$a->getAttribute("href")."<br/>";
}

Как указано выше :) Слишком медленно ..

4 голосов
/ 10 июля 2017

Самый простой способ, evaluate предназначен для этой задачи!

Самый простой способ получить значение - evaluate() метод :

$xp = new DOMXPath($dom);
$v = $xp->evaluate("string(/etc[1]/@stringValue)");

Примечание: важно ограничить возврат XPath 1 элементом (в данном случае первым a) и cast значением с 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 ... Когда информация уже существует в узле,используйте то, что предлагает лучшую производительность , в качестве методов getAttribute(), saveXML() и т. д. и свойства как $nodeValue, $textContent и т. д. , предоставленные DOMNode.Смотрите ответ @ Гордона для этой конкретной проблемы.Подзапрос XPath (в контексте) подходит для сложных случаев - или для упрощения кода, избегая проверки цикла hasChildNodes () + для $ childNodes и т. Д.без значительного увеличения производительности.

...