web-dev-qa-db-ja.com

DOMXpath-a要素のhref属性とテキスト値を取得します

だから私はこのようなHTML文字列を持っています:

<td class="name">
   <a href="/blah/somename23123">Some Name</a>
</td>
<td class="name">
   <a href="/blah/somename28787">Some Name2</a>
</td>

XPathを使用すると、次のXpathクエリを使用してhref属性の値を取得できます。

 $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) {...}

今、知りたいのですが、これら2つのクエリを組み合わせて、1つのクエリだけで両方の値を取得するにはどうすればよいですか(それが可能な場合でも可能ですか)。

18

Fetch

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

次に、nodeValueを使用してテキストを取得し、getAttribute('href')を使用して属性を取得します。

それとは別に、Xpathクエリを結合演算子_|_と組み合わせて、

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

同じように。

20
Gordon

コードを1つのループに減らすには、次のことを試してください。

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

上記のように:)遅すぎる..

15
Ryan

最も簡単な方法は、evaluateがこのタスクに使用することです。

値を取得する最も簡単な方法は [evaluate() method

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

注:XPathの戻りを1アイテム(この場合は最初のa)に制限することが重要であり、caststring()または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によって提供
この特定の問題については、@ Gordonの回答を参照してください。
XPath subquery(コンテキストで)は複雑なケースに適しています—または、コードを単純化して、hasChildNodes() +のループをチェックしないようにします$ childNodesなど。パフォーマンスの大幅な向上はありません。

4
Peter Krauss