【问题标题】:PHP - DOMXpath - Get the resultPHP - DOMXpath - 获取结果
【发布时间】:2012-05-10 21:27:37
【问题描述】:

当我想使用 XPath 打印评估表达式的结果时出现错误。

$url = $xpath->evaluate('//a/@href', $event); 回声 $url ;

我有这个错误:可捕获的致命错误:DOMNodeList 类的对象无法转换为字符串

我的代码:

<?php
    // Get the HTML Source Code
    $url='http://www.parisbouge.com/events/2012/05/01/';
    $source = file_get_contents($url);

    // DOM document Creation
    $doc = new DOMDocument;
    $doc->loadHTML($source);

    // DOM XPath Creation
    $xpath = new DOMXPath($doc);

    // Get all events
    $events = $xpath->query('//li[@class="nom"]');

    // Count number of events
    printf('There is %d events<br />', $events->length);

    // List all events
    for($i = 0; $i < ($events->length); $i++) {
        $event = $events->item($i);
        $url = $xpath->evaluate('//a/@href', $event);
        $nom = $xpath->evaluate('//a/text()', $event);
        $lieu = $xpath->evaluate('../li[@class="lieu"]/a/text()', $event);
        echo "Result : $url $nom $lieu <br/>";
    }
?>

【问题讨论】:

  • 我不能说评估函数调用中路径的正确性,但我的经验是,与文档中所暗示的相反,如果仅表达式,评估不会返回标量值产生一个节点。但是,如果表达式导致单个节点并且您在路径中使用显式类型转换,则评估将返回一个标量。因此,如果读取为 $url = $xpath->evaluate('string(//a/@href)', $event);

标签: php xpath domdocument domxpath evaluate


【解决方案1】:

引用http://php.net/manual/de/domxpath.evaluate.php

如果可能,返回一个类型化的结果或一个包含所有与给定 XPath 表达式匹配的节点的 DOMNodeList。

所以您的 XPath 显然会返回多个节点,这可能源于您使用 //,这意味着“到处查找”。如果您执行echo $url-&gt;length;,您将看到有 460 个项目(无论传递的上下文节点如何)。

来自http://www.w3.org/TR/xpath/#path-abbrev

  • //para 选择文档根的所有 para 后代,因此选择同一文档中的所有 para 元素作为上下文节点
  • .//para 选择上下文节点的 para 元素后代

所以你需要改用.//a/@href。这将只为echo $url-&gt;length; 提供 1 个结果,但它不能作为类型化结果返回,因此您必须将代码更改为

$url = $xpath->evaluate('string(.//a/@href)', $event);
$nom = $xpath->evaluate('string(.//a)', $event);
$lieu = $xpath->evaluate('string(../li[@class="lieu"]/a)', $event);

还请注意,您可以将 DOMDocument 创建和加载时间缩短到

libxml_use_internal_errors(true);
$doc = new DOMDocument;
$doc->loadHTMLFile('http://www.parisbouge.com/events/2012/05/01/');

libxml_use_internal_errors 的调用将抑制任何解析错误。

【讨论】:

    【解决方案2】:

    试试这个以获取有关节点的信息。

     // List all events
    for($i = 0; $i < ($events->length); $i++) {
        $event = $events->item($i);
        $url = $xpath->evaluate('.//a/@href', $event);
        $nom = $xpath->evaluate('.//a/text()', $event);
        $lieu = $xpath->evaluate('../li[@class="lieu"]/a/text()', $event);
    
        $result = '';
        if ($url->length > 0) {
            $result .= $url->item(0)->value;
        }
    
        if ($nom->length > 0) {
            $result .= $nom->item(0)->wholeText;
        }
    
        if ($lieu->length > 0) {
            $result .= $lieu->item(0)->wholeText;
        }
    
        echo $result . "<br />";
        //echo "Result : " . $url->item(0)->value . ' | ' . $nom->item(0)->wholeText  . ' | ' . $lieu->item(0)->wholeText . "<br/>";
    }
    

    不要忘记添加检查节点是否存在等。要检查是否有任何节点,您可以检查节点列表长度或抑制“戈登”建议的错误。

    【讨论】:

    • 如何检查节点是否存在?
    【解决方案3】:

    试试

    $url = $xpath->evaluate('string(.//a/@href)', $event); echo $url ;
    

    这将为您提供包含在 $event 中的第一个 ahref 作为字符串,而不是节点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-12-05
      • 2013-02-20
      • 2014-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多