如何在DOMNode上执行XPath查询? [英] How do I do an XPath query on a DOMNode?

查看:113
本文介绍了如何在DOMNode上执行XPath查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法在DOMNode上执行xpath查询?或至少将其转换为DOMXPath?

 < html> 
...
< div id =content>
...
< div class =listing>
...
< div>< / div>
< div>< / div>
< div class ='foo'>
< h3>获取1< / h3>
< a>和我也1< / a>
< / div>
< / div>
< div class =listing>
...
< div>< / div>
< div>< / div>
< div class ='foo'>
< h3> Get me 2< / h3>
< a>和我也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)
{
//我想进一步挖掘这里使用DOMNode上的查询
}


解决方案

将节点作为第二个参数传递给 DOMXPath :: query


contextnode :可以指定可选的contextnode进行相对的XPath查询。默认情况下,查询与根元素相关。


示例:

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

这使用 UNION运算符的结果

得到我1 
和我也1
让我2
和我也1

如果您不需要任何复杂的查询,您还可以执行

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

甚至通过迭代子节点(注意这个包括所有文本节点)

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

然而,所有这些都是不必要的,因为你可以获取这些节点直接:

  $ nodes = $ x_path-> query(/ html / body // div [@ class = '列出'] /格[最后()]); 

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

将给你所有div的最后一个div子节点的两个节点,列出并输出组合的文本节点值的类属性值,包括空格

  0 
获取1
和我也1

1
让我2
和我也1

同样,以下

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

将给你四个孩子H3和A节点并输出

  0获取1 
1and我也是1
2Get我2
3和我也1

如果你需要通过名称来区分这些名称,您可以执行

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

然后会给

  0h3获取1 
1aand我也是1
2h3收获我2
3a和我也1
/ pre>

Is there a way to do an xpath query on a DOMNode? Or at least convert it to a 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>

This is my code. I am trying to get a list of array that has the values of the h3 and a tags in each array. To do that, I needed to get each listing, and then get the h3 and a tag's value in each listing.

$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
}

解决方案

Pass the node as the second argument to DOMXPath::query

contextnode: The optional contextnode can be specified for doing relative XPath queries. By default, the queries are relative to the root element.

Example:

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

This uses the UNION operator for a result of

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

If you don't need any complex querying, you can also do

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

Or even by iterating the child nodes (note that this includes all the text nodes)

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

However, all of that is unneeded since you can fetch these nodes directly:

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

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

will give you two nodes in the last div child of all the divs with a class attribute value of listing and output the combined text node values, including whitespace

0
           Get me 1
           and me too 1

1
           Get me 2
           and me too 1

Likewise, the following

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

will give you the four child H3 and A nodes and output

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

If you need to differentiate these by name while iterating over them, you can do

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

which will then give

0h3Get me 1
1aand me too 1
2h3Get me 2
3aand me too 1

这篇关于如何在DOMNode上执行XPath查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆