27

DOMNode で xpath クエリを実行する方法はありますか? または、少なくとも DOMXPath に変換しますか?

<html>
  ...
  <div id="content">
     ...
     <div class="listing">
         ...
         <div></div>
         <div></div>
         <div  class='foo'>
           <h3>Get me 1</h3>
           <a>and me too 1</a>
         </div>
     </div>
     <div class="listing">
         ...
         <div></div>
         <div></div>
         <div class='foo'>
           <h3>Get me 2</h3>
           <a>and me too 1</a>
         </div>
     </div>
     ....
  </div>
</html>

これは私のコードです。各配列に h3 とタグの値を持つ配列のリストを取得しようとしています。そのためには、各リストを取得してから、各リストで h3 とタグの値を取得する必要がありました。

$html_dom = new DOMDocument();
@$html_dom->loadHTML($html);
$x_path = new DOMXPath($html_dom);

$nodes= $x_path->query("//div[@id='content']//div[@class='listing']");

foreach ($nodes as $node)
{
  // I want to further dig down here using query on a DOMNode
}
4

3 に答える 3

43

2 番目の引数としてノードを渡しますDOMXPath::query

contextnode : オプションの contextnode は、相対 XPath クエリを実行するために指定できます。デフォルトでは、クエリはルート要素に対して相対的です。

例:

foreach ($nodes as $node) {
    foreach ($x_path->query('h3|a', $node) as $child) {
        echo $child->nodeValue, PHP_EOL;
    }
}

これは、次の結果にUNION 演算子を使用します。

Get me 1
and me too 1
Get me 2
and me too 1

複雑なクエリが必要ない場合は、次のこともできます

foreach ($nodes as $node) {
    foreach ($node->getElementsByTagName('a') as $a) {
      echo $a->nodeValue, PHP_EOL;
    }
}

または、子ノードを反復することによっても (これにはすべてのテキスト ノードが含まれることに注意してください)。

foreach ($nodes as $node) {
    foreach ($node->childNodes as $child) {
      echo $child->nodeName, PHP_EOL;
    }
}

ただし、これらのノードを直接取得できるため、これらはすべて不要です。

$nodes= $x_path->query("/html/body//div[@class='listing']/div[last()]");

foreach ($nodes as $i => $node) {
    echo $i, $node->nodeValue, PHP_EOL;
}

リストのクラス属性値を持つすべてのdivの最後のdivの子に2つのノードを与え、空白を含む結合されたテキストノード値を出力します

0
           Get me 1
           and me too 1

1
           Get me 2
           and me too 1

同様に、次の

"//div[@class='listing']/div[last()]/node()[name() = 'h3' or name() = 'a']"

4 つの子 H3 および A ノードと出力が得られます

0Get me 1
1and me too 1
2Get me 2
3and me too 1

これらを反復しながら名前で区別する必要がある場合は、次のことができます。

foreach ($nodes as $i => $node) {
    echo $i, $node->nodeName, $node->nodeValue, PHP_EOL;
}

それはそれから与えるでしょう

0h3Get me 1
1aand me too 1
2h3Get me 2
3aand me too 1
于 2013-05-24T05:25:57.030 に答える
17

$nodeをコンテキスト ノードとして提供します。

foreach ($nodes as $node)
{
   $morenodes = $x_path->query(".//h3", $node);
}

$contextnodeマニュアルを参照してください: http://php.net/manual/en/domxpath.query.php

于 2013-05-24T03:52:52.510 に答える
4

完全にするためにDOMNode::getNodePath、そのノードの xpath を返すメソッドがあります。だからあなたも使うことができます$x_path->query($node->getNodePath().'//h3')

于 2016-06-07T12:38:18.933 に答える