【问题标题】:How to display a specific XML node attribute?如何显示特定的 XML 节点属性?
【发布时间】:2016-07-14 15:54:47
【问题描述】:

我想在我的网站上创建一个简单的“新闻”小部件,链接到我的 Squarespace 博客的 RSS 提要。

RSS 源可以在这里找到:https://weboxsite.squarespace.com/?format=rss

当我从 CURL 函数加载 XML 数据时,当我 print_r() 我的 XML 文件时,我看不到某些节点。

尤其是我想获取节点属性<media>

在获取我的<media>节点的属性时,我无法获取url属性。

我已经简化了来自网络的结果,以便于阅读。

<item>
<title>Google Disque : un outil indispensable</title>
<category>Google drive</category>
<dc:creator></dc:creator>
<pubDate>Wed, 22 Jun 2016 21:25:37 +0000</pubDate>
<link>
http://blogue.webox.site/touslesarticles/2016/6/22/google-disque-un-outil-indispensable
</link>
<guid isPermaLink="false">
5769a85b9de4bbf4535c1896:5769a8f1bebafb833a859939:576b01e48419c2d2589b7264
</guid>
<description>
My excerpt....
</description>
<content:encoded>
<![CDATA[
<p>My content....</p> 
]]>
</content:encoded>
<media:content type="image/jpeg" url="http://static1.squarespace.com/static/5769a85b9de4bbf4535c1896/5769a8f1bebafb833a859939/576b01e48419c2d2589b7264/1466630737869/1500w/googledisque_bg.jpg" medium="image" isDefault="true" width="510" height="334">
<media:title type="plain">Google Disque : un outil indispensable</media:title>
</media:content>
</item>

** 主要问题**

<media:content type="image/jpeg" url="http://static1.squarespace.com/static/5769a85b9de4bbf4535c1896/5769a8f1bebafb833a859939/576b01e48419c2d2589b7264/1466630737869/1500w/googledisque_bg.jpg" medium="image" isDefault="true" width="510" height="334">
    <media:title type="plain">Google Disque : un outil indispensable</media:title>
    </media:content>

这是我目前的代码

<?php 
$limit = 4;

    $c=curl_init('https://weboxsite.squarespace.com/?format=rss');

    curl_setopt( $c, CURLOPT_USERAGENT,'nesss' );
    curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
    $r=curl_exec( $c );
    curl_close( $c );

    $rss = new DOMDocument();
    $rss->loadxml($r);

    $feed = array();

    foreach ($rss->getElementsByTagName('item') as $node) {

        $item = array ( 
            'title'     =>  $node->getElementsByTagName('title')->item(0)->nodeValue,
            'link'      =>  $node->getElementsByTagName('link')->item(0)->nodeValue,
            'media'     =>  $node->getElementsByTagName('media')->item(0)->nodeValue,
            'cat'       =>  $node->getElementsByTagName('category')->item(0)->nodeValue
        );

        array_push($feed, $item);
    }

    for($x = 0; $x < $limit; $x++) {

        $title  = str_replace(' & ', ' &amp; ', $feed[$x]['title']);
        $link   = $feed[$x]['link'];
        $desc   = $feed[$x]['media'];
        $cat   = $feed[$x]['cat'];

        echo '<p><strong><a href="'.$link.'" title="'.$title.'">'.$title.'</a></strong></p>';
        echo '<p>'.$cat.'</p>';

    }

    ?>

我知道这样做'media' =&gt; $node-&gt;getElementsByTagName('media')-&gt;item(0)-&gt;nodeValue 不是这样做的好方法,因为它试图呈现值。

我试图放置'media'=&gt; $node-&gt;getElementsByTagName('media')-&gt;item(0)-&gt;getAttribute('url'),但我收到了一个错误。

Call to a member function getAttribute() on null in ...

我可能认为这是因为节点被命名为 media:content 并且不仅是媒体,而且事件发生了变化,它无处可去。

我是不是有什么地方遗漏了?

【问题讨论】:

标签: php xml rss domdocument


【解决方案1】:

media: 的元素位于不同的 XML 命名空间中。因为您正在阅读应该是 Media-RSS 的 RSS。查找属性xmlns:media="http://search.yahoo.com/mrss/"。这是命名空间的定义。解析器将前缀解析为实际的命名空间。

  • media:content -> {http://search.yahoo.com/mrss/}content
  • media:title -> {http://search.yahoo.com/mrss/}title

由于元素位于命名空间中,因此您必须使用命名空间感知方法:

$title = $node->getElementsByTagNameNS(
  'http://search.yahoo.com/mrss/', 'title'
)->item(0)->nodeValue;

或者您使用 Xpath 表达式并注册您自己的前缀。

$rss = new DOMDocument();
$rss->loadxml($r);
$xpath = new DOMXpath($rss);
$xpath->registerNamespace('m', 'http://search.yahoo.com/mrss/');

$feed = array();
foreach ($xpath->evaluate('//item') as $node) {
    $feed[] = array( 
        'title' => $xpath->evaluate('string(title)', $node),
        'link' => $xpath->evaluate('string(link)', $node),
        'media-title' => $xpath->evaluate('string(m:content/m:title)', $node),
        'cat' => $xpath->evaluate('string(category)', $node)
    );
}

【讨论】:

    【解决方案2】:

    尝试使用:

    getElementsByTagNameNS ( string $namespaceURI , string $localName )
    

    这里是您文件中的命名空间URI:

    xmlns:content="http://purl.org/rss/1.0/modules/content/"

    xmlns:wfw="http://wellformedweb.org/CommentAPI/"

    xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"

    xmlns:dc="http://purl.org/dc/elements/1.1/"

    xmlns:media="http://www.rssboard.org/media-rss"

    最后:

    'media' =&gt; $node-&gt;getElementsByTagName('content')-&gt;item(0)-&gt;nodeValue

    变成

    'media' =&gt; $node-&gt;getElementsByTagNameNS('http://www.rssboard.org/media-rss','content')-&gt;item(0)-&gt;getAttribute('url')

    请记住:"NAMESPACE:NODENAME",所以您要查找的是 content 而不是 media

    希望对您有所帮助。

    【讨论】:

    • 有了你给我的新代码行,我就有了。 [0] => Array ( [title] => Google Disque : un outil 不可或缺 [link] => blogue.webox.site/touslesarticles/2016/6/22/… [media] => Google Disque : un outil 不可或缺 [cat] => Google drive ) 看起来它返回媒体标题的值(Google Disque : un outil 必不可少的)而不是 URL 属性值。
    • 或者更好地测试一下,我在这里的重点是告诉你关于 XML 中的命名空间。休息在你身上。
    • XML 有点棘手,去阅读 ThW 的下一个答案,比我的要好。
    • 谢谢,我去看看。
    猜你喜欢
    • 2019-02-22
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 2013-05-16
    • 2015-01-06
    • 2018-10-04
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多