2

我正在使用 Yandex API 创建一个元搜索引擎。Yandex 以 XML 格式给出结果。所以我们需要遍历 XML 响应以获取不同的字段,如 URL、标题、描述等。

Yandex 的 XML 响应如下: http: //pastebin.com/kAVAVri9

这就是我实现的方式:粘贴

$dom5 = new DOMDocument();

if ($dom5->loadXML($site_results)) {

    $results  = $dom5->getElementsByTagName("response");
    $results1 = $results->getElementsByTagName("results");
    $results2 = $results1->getElementsByTagName("group");


    $totals["yandex"] = 1000;


    foreach ($results1 as $link) {

        $url = $link->getElementsByTagName("doc")->item(2)->nodeValue;
        ;
        $url = str_replace('http://', '', $url);
        if (substr($url, -1, 1) == '/') {
            $url = substr($url, 0, strlen($url) - 1);
        }
        $search_results[$i]["url"] = $url;

        $title                       = $link->getElementsByTagName("doc")->item(4)->nodeValue;
        $search_results[$i]["title"] = $title;
        $test                        = $link->getElementsByTagName("doc");
        $test1                       = $test->getElementsByTagName("title");
        $desc                        = $test1->getElementsByTagName("headline")->item(0)->nodeValue;
        $search_results[$i]["desc"]  = $desc;

        $search_results[$i]["engine"]   = 'yandex';
        $search_results[$i]["position"] = $i + 1;
        $i++;

    }
}

我是 php 新手。如果我犯了一些愚蠢的错误,请原谅我。我无法通过我的实施来检索结果。请帮我找出错误并从 xml 响应中获取必要的字段。谢谢!

4

1 回答 1

3

该方法getElementsByTagName()返回一个DOMNodeList

$results  = $dom5->getElementsByTagName("response");

DOMNodeList没有名为 的方法,getElementsByTagName()您调用它:

$results1 = $results->getElementsByTagName("results");

因此触发了致命错误:每当在 PHP 中对不存在的对象执行方法时,您将收到致命错误并且脚本停止工作。

不要调用未定义的对象方法,你应该没问题。

除了这些基础知识,对于解析此类 XML 文档,我通常建议使用 SimpleXML,但是此 XML 文件有点具体,因此我建议从 SimpleXML 扩展并添加您可能需要使用的功能,部分来自正则表达式以及 DOMDocument .

解析这些 XML 文件时应该了解的一个概念是 Xpath。例如,要访问您在上面遇到很多问题的元素,您可以逐字编写路径:

/*/response/results/grouping/group

在带有 SimpleXML 的 PHP 中,这看起来像:

$url = 'http://pastebin.com/raw.php?i=kAVAVri9';
$xml = simplexml_load_file($url, 'MySimpleXML');
foreach ($xml->xpath('/*/response/results/grouping/group') as $link) {
    # ... operate on $link
}

一个更大的例子:

$url = 'http://pastebin.com/raw.php?i=kAVAVri9';
$url = '../data/yandex.xml';
$xml = simplexml_load_file($url, 'MySimpleXML');
foreach ($xml->xpath('/*/response/results/grouping/group') as $link) {
    $url      = $link->doc->url->str()->preg('~^https?://(.*?)/*$~u', '$1');
    $title    = $link->doc->title->text();
    $headline = $link->doc->headline->text();
    printf("<%s> %s\n%s\n\n", $url, $title, wordwrap($headline));
}

这是典型的输出:

<www.facebook.com> " Facebook" - a social networking service
Allows users to find and communicate with friends, classmates and
colleagues, share thoughts, photos and videos, and join various groups.

<en.wikipedia.org/wiki/Facebook>  Facebook - Wikipedia, the free encyclopedia
 Facebook is a social networking service launched in February 2004, owned
and operated by Facebook, Inc. As of September 2012, Facebook has over one
billion active users, more than half of them using Facebook on a mobile
device.

<mashable.com/category/facebook>  Facebook 

...

上面的 PHP 代码示例需要更多代码才能工作,因为它从 SimpleXML 扩展而来以便于使用。这是通过以下代码完成的:

class MySimpleXML extends SimpleXMLElement
{
    public function text()
    {
        $string = null === $this[0] ? ''
            : (dom_import_simplexml($this)->textContent);

        return $this->str($string)->normlaizeWS();
    }

    public function str($string = null)
    {
        return new MyString($string ?: $this);
    }
}

class MyString
{
    private $string;

    public function __construct($string)
    {
        $this->string = $string;
    }

    public function preg($pattern, $replacement)
    {
        return new self(preg_replace($pattern, $replacement, $this));
    }

    public function normlaizeWS()
    {
        return $this->preg('~\s+~', ' ');
    }

    public function __toString()
    {
        return (string) $this->string;
    }
}

刚开始这可能有点多,请查看 SimpleXML 的 PHP 手册和代码示例中使用的其他函数。

于 2013-03-16T00:42:41.610 回答