1
votes

How can I get the contest logo and start date from this RSS feed? I can get the dc:modified child for example but always get a blank for anything from dc:dataset.

My code:

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

The RSS feed:

<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>
2

2 Answers

2
votes

The contest_logo and start_date are in the empty namespace. You have to switch back. Additionally it is not good to reply on namespace prefixes defined in the document. Use the namespace URI (for example defined as mapping array in your code).

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

Output:

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

In DOM you would register an alias on the Xpath processor and use it in the expressions. Here is a demo:

$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>";
}
0
votes

Another alternative - use 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";

Output:

   619130 
    
2021-02-09 07:50:10

     20210110