【问题标题】:How do I get the child nodes of this RSS feed?如何获取此 RSS 提要的子节点?
【发布时间】:2023-04-06 10:49:02
【问题描述】:

如何从这个 RSS 提要中获取比赛徽标和开始日期?例如,我可以获取 dc:modified 子对象,但对于 dc:dataset 中的任何内容,总是会得到一个空白。

我的代码:

$feed_url = 'https://www.website.com/?call_custom_simple_rss=1&csrp_post_type=contest&csrp_posts_per_page=2&csrp_show_meta=1';
$feed = file_get_contents($feed_url);
$rss = simplexml_load_string($feed);

foreach($rss->channel->item as $entry) {    
    echo $entry->children("dc", true)->modified . "<br>";
    echo $entry->children("dc", true)->dataset->contest_logo . "<br>";
    echo $entry->children("dc", true)->dataset->start_date . "<br>";
}

RSS 提要:

<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:wp="http://wordpress.org/export/1.2/" xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/" version="2.0">
<channel>
<title>RSS Title</title>
<description>A website</description>
<lastBuildDate>Wed, 17 Feb 2021 15:03:03 +0000</lastBuildDate>
<item>
<title>
<![CDATA[ Photography Awards ]]>
</title>
<link>
<![CDATA[ /contests/photography-awards/ ]]>
</link>
<pubDate>Mon, 11 Jan 2021 13:52:27 -0600</pubDate>
<dc:identifier>619116</dc:identifier>
<dc:modified>2021-02-09 07:50:10</dc:modified>
<dc:created unix="1610373147">2021-01-11 13:52:27</dc:created>
<dc:dataset>
<contest_logo>
<![CDATA[ 619130 ]]>
</contest_logo>
<start_date>
<![CDATA[ 20210110 ]]>
</start_date>
</dc:dataset>
</item>
</channel>
</rss>

【问题讨论】:

    标签: php xml wordpress rss simplexml


    【解决方案1】:

    contest_logostart_date 位于空命名空间中。你必须换回来。此外,对文档中定义的命名空间前缀进行回复是不好的。使用命名空间 URI(例如在您的代码中定义为映射数组)。

    $rss = simplexml_load_string($feed);
    $xmlns = [
        'dc' => 'http://purl.org/dc/elements/1.1/'
    ];
    
    foreach($rss->channel->item as $entry) {    
        echo $entry->children($xmlns['dc'])->modified . "<br>";
        echo $entry->children($xmlns['dc'])->dataset->children('')->contest_logo . "<br>";
        echo $entry->children($xmlns['dc'])->dataset->children('')->start_date . "<br>";
    }
    

    输出:

    2021-02-09 07:50:10<br>
     619130 
    <br>
     20210110 
    <br>
    

    在 DOM 中,您将在 Xpath 处理器上注册一个别名并在表达式中使用它。这是一个演示:

    $document = new DOMDocument();
    $document->loadXML($feed);
    $xpath = new DOMXpath($document);
    $xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
    
    foreach ($xpath->evaluate('/rss/channel/item') as $entry) {
        echo $xpath->evaluate('string(dc:modified)', $entry). "<br>";
        echo $xpath->evaluate('string(dc:dataset/contest_logo)', $entry). "<br>";
        echo $xpath->evaluate('string(dc:dataset/start_date)', $entry). "<br>";
    }
    

    【讨论】:

    • 请注意,您也可以使用 SimpleXML use XPathnamespaces for it are registered in much the same way
    • 是的,但是您必须在要使用它们的每个 SimpleXMLElement 上重新注册它们。
    • 啊,非常正确。现在我终于明白了为什么 DOM 有用于 XPath 查询的中间对象,而我从来不需要它,因为我一次只做一个查询。 :)
    【解决方案2】:

    另一种选择 - 使用 xpath:

    echo  $rss->xpath('//dc:dataset/contest_logo')[0] . "\r\n";
    echo  $rss->xpath('//dc:modified')[0] . "\r\n";
    echo  $rss->xpath('//start_date')[0] . "\r\n";
    

    输出:

       619130 
        
    2021-02-09 07:50:10
    
         20210110 
    

    【讨论】:

      猜你喜欢
      • 2016-04-05
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-04
      相关资源
      最近更新 更多