Parse feed media group with array of children - php

I have this XML feed:
<item>
<title>Title</title>
<media:group>
<media:content url="http://example.it/image.jpg" type="image/jpeg">
<media:thumbail url="http://example.it/image.jpg" type="image/png"/>
<media:credit>Credit</media:credit>
</media:content>
<media:content url="http://example.it/image2.jpg" type="image/jpeg">
<media:thumbail url="http://example.it/image2.jpg" type="image/png"/>
<media:credit>Credit2</media:credit>
</media:content>
</media:group>
</item>
This is my PHP code for read it:
$rss = new SimpleXMLElement($url);
foreach ($rss->channel->item as $item) {
$title = $item->title;
}
No problem reading "title" item, but how can I read "url", "thumbnail", "credit" for each media:content?
-------SOLVED-------
$rss = new SimpleXMLElement($url);
foreach ($rss->channel->item as $item) {
$title = $item->title;
$gallerie = $item->children('http://search.yahoo.com/mrss/')->group->content;
foreach($gallerie as $g) {
echo $g->attributes()['url'] ."<br/>";
}
}

Related

PHP SimpleXML: How to access nested namespaces?

Given this XML structure:
$xml = '<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<channel>
<item>
<title>Title</title>
<media:group>
<media:content url="url1" />
<media:content url="url2" />
</media:group>
</item>
<item>
<title>Title2</title>
<media:group>
<media:content url="url1" />
<media:content url="url2" />
</media:group>
</item>
</channel>
</rss>';
$xml_data = new SimpleXMLElement($xml);
How do I access the attributes of the media:content nodes? I tried
foreach ($xml_data->channel->item as $key => $data) {
$urls = $data->children('media', true)->children('media', true);
print_r($urls);
}
and
foreach ($xml_data->channel->item as $key => $data) {
$ns = $xml->getNamespaces(true);
$urls = $data->children('media', true)->children($ns['media']);
print_r($urls);
}
as per other answers, but they both return empty SimpleXMLElements.
When you echo out XML with SimpleXML, you need to use asXML() to see the real content, print_r() does it's own version and doesn't show all the content...
foreach ($xml_data->channel->item as $key => $data) {
$urls = $data->children('media', true)->children('media', true);
echo $urls->asXML().PHP_EOL;
}
echos out...
<media:content url="url1"/>
<media:content url="url1"/>
It only outputs the first one of each group as you will need to add another foreach to go through all of the child nodes for each element.
foreach ($xml_data->channel->item as $key => $data) {
echo $data->title.PHP_EOL;
foreach ( $data->children('media', true)->children('media', true) as $content ) {
echo $content->asXML().PHP_EOL;
}
}
outputs..
Title
<media:content url="url1"/>
<media:content url="url2"/>
Title2
<media:content url="url1"/>
<media:content url="url2"/>
To access a particular attribute (so for example the url attribute from the second code example) you have to use the attributes() method...
echo $content->attributes()['url'];

PHP - how to display soap response sub children list

I got a response in the following xml format like below:
How can I get list->item->value in one row or container:
<list>
<item>
<Key>3</Key>
<Value>3960</Value>
</item>
<item>
<Key>5</Key>
<Value>3967</Value>
</item>
<item>
<Key>6</Key>
<Value>3968</Value>
</item>
</list>
How can I display the value like this below
<table>
<tr>
<td>3960, 3967, 3968</td>
<td>3963, 3961, 3960</td>
</tr>
</table>
and at the moment I try to use children() in foreach, but it returns error: Call to a member function children() on null, and below is my php code
foreach($items as $item){
echo '<td>';
$child_item = '';
foreach($item->list->children()->children() as $child)
{
$child_item .= $child .' ,';
}
echo rtrim($child_item,' ,');
echo '</td>';
}
Thanks experts!
This is what you need to achieve that:
<?php
$xmlstr = <<<XML
<root>
<list>
<item>
<Key>3</Key>
<Value>3960</Value>
</item>
<item>
<Key>5</Key>
<Value>3967</Value>
</item>
<item>
<Key>6</Key>
<Value>3968</Value>
</item>
</list>
<list>
<item>
<Key>3</Key>
<Value>3963</Value>
</item>
<item>
<Key>5</Key>
<Value>3961</Value>
</item>
<item>
<Key>6</Key>
<Value>3960</Value>
</item>
</list>
</root>
XML;
$items = new SimpleXMLElement($xmlstr);
echo "<table>\r\n";
echo "<tr>\r\n";
foreach($items as $list){
echo "<td>";
$itemsArr = array();
foreach($list as $item){
$itemsArr[] = $item->Value[0];
}
echo implode(", ", $itemsArr);
echo "</td>\r\n";
}
echo "</tr>\r\n";
echo "</table>";
?>

Problems on reading image url from a rss feed, using DOMDocument

I have a rss feed
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
<item>
<title>VIDEO: Have you heard of Alibaba?</title>
<description>Alibaba is the world's biggest e-commerce firm but most people in the West haven't heard of it.</description>
<link>http://www.bbc.co.uk/news/business-29216696#sa-ns_mchannel=rss&ns_source=PublicRSS20-sa</link>
<guid isPermaLink="false">http://www.bbc.co.uk/news/business-29216696</guid>
<pubDate>Tue, 16 Sep 2014 02:29:17 GMT</pubDate>
<media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/77609000/jpg/_77609399_73619721.jpg"/>
<media:thumbnail width="144" height="81" url="http://news.bbcimg.co.uk/media/images/77609000/jpg/_77609400_73619721.jpg"/>
</item>
<item>
<title>VIDEO: Phones 4U shops closing for business</title>
<description>Retailer Phones 4U has gone into administration putting 5,596 jobs at risk.</description>
<link>http://www.bbc.co.uk/news/business-29202179#sa-ns_mchannel=rss&ns_source=PublicRSS20-sa</link>
<guid isPermaLink="false">http://www.bbc.co.uk/news/business-29202179</guid>
<pubDate>Mon, 15 Sep 2014 22:15:50 GMT</pubDate>
<media:thumbnail width="66" height="49" url="http://news.bbcimg.co.uk/media/images/77587000/jpg/_77587217_77587209.jpg"/>
<media:thumbnail width="144" height="81" url="http://news.bbcimg.co.uk/media/images/77587000/jpg/_77587218_77587209.jpg"/>
</item>
</rss>
I am able to read title, description from this rss, using php's DOMDocument class.
Following is my code
$xml = 'http://feeds.bbci.co.uk/news/video_and_audio/business/rss.xml' ;
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$items=$xmlDoc->getElementsByTagName('item');
foreach($items as $item){
$item_title= $item->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
$item_link= $item->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
$item_desc= $item->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;
}
But how can able to read url of 'media:thumbnail' tag of each item ?
Since it has namespaces, use getElementsByTagNameNS() together with ->getAttribute() in this case. Example:
$xml = 'http://feeds.bbci.co.uk/news/video_and_audio/business/rss.xml' ;
$xmlDoc = new DOMDocument();
$xmlDoc->load($xml);
$items = $xmlDoc->getElementsByTagName('item');
foreach($items as $key => $item) {
$item_title= $item->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
$item_link= $item->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
$item_desc= $item->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;
$media = $item->getElementsByTagNameNS('http://search.yahoo.com/mrss/', 'thumbnail');
foreach($media as $thumb) {
echo $thumb->getAttribute('url') . '<br/>';
}
}
SimpleXMLElement Variant:
$xml = simplexml_load_file('http://feeds.bbci.co.uk/news/video_and_audio/business/rss.xml');
foreach($xml->channel->item as $item) {
$title = $item->title;
$description = $item->description;
$link = $item->link;
$media = $item->children('media', 'http://search.yahoo.com/mrss/');
foreach($media->thumbnail as $thumb) {
echo $thumb->attributes()->url . '<br/>';
}
}
Use Xpath. It is part of the DOM extension and allows you to use expressions to fetch nodes and values from a DOM. Like XML itself Xpath allows you define prefixes/aliases for the namespaces.
$dom = new DOMDocument;
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('m', 'http://search.yahoo.com/mrss/');
$xpath->registerNamespace('a', 'http://www.w3.org/2005/Atom');
foreach ($xpath->evaluate('//item') as $itemNode) {
$item = [
'title' => $xpath->evaluate('string(title)', $itemNode),
'link' => $xpath->evaluate('string(link)', $itemNode),
'description' => $xpath->evaluate('string(description)', $itemNode),
];
foreach ($xpath->evaluate('m:thumbnail/#url', $itemNode) as $urlAttribute) {
$item['thumbnails'][] = $urlAttribute->value;
}
var_dump($item);
}

PHP xml array parsing data

Hey all i have this type of XML i am trying to get data from. This is just a snip of the large XML code:
<entry>
<id>http://www.google.com/calendar/feeds/[Letters/numbers here]group.calendar.google.com/public/basic/[Letters/numbers here]</id>
<published>2013-08-01T13:40:24.000Z</published>
<updated>2013-08-01T13:40:24.000Z</updated>
<title type='html'>[Title Here]</title>
<summary type='html'>When: Tue Sep 24, 2013 7am</summary>
<content type='html'>When: Tue Sep 24, 2013 7am
<br />Event Status: confirmed
</content>
<link rel='alternate' type='text/html' href='https://www.google.com/calendar/event?eid=[Letters/numbers here]' title='alternate'/>
<link rel='self' type='application/atom+xml' href='https://www.google.com/calendar/feeds/[Letters/numbers here]group.calendar.google.com/public/basic/[Letters/numbers here]'/>
<author>
<name>[email here]</name>
<email>[email here]</email>
</author>
</entry>
etc... etc....
Currently i can get both published and updated just fine by doing the following:
<?php
$url = strtolower($_GET['url']);
$doc = new DOMDocument();
$doc->load('http://www.google.com/calendar/feeds/[number/letters here].calendar.google.com/public/basic');
$entries = $doc->getElementsByTagName("entry");
foreach ($entries as $entry) {
$tmpPublished = $entry->getElementsByTagName("published");
$published = $tmpPublished->item(0)->nodeValue;
$tmpUpdated = $entry->getElementsByTagName("updated");
$updated = $tmpUpdated->item(0)->nodeValue;
}
?>
However i am unsure as to how to get the inner data from within the parent array - that being link in this case.
So i need to get
link->href
I would imagine it would be:
$tmpLink = $entry->getElementsByTagName("link");
$link = $tmpLink->item( 2 )->nodeValue;
Any help would be great!
you can use:
$links = $doc->getElementsByTagName("link");
foreach ($links as $link) {
$href = $link->getAttribute("href");
}
if you want to get href... hope that I understood what you wanted :)
You can do this with simplexml_load_string like following codes:
$entries = simplexml_load_string($string);
foreach ($entries as $entry) {
echo $entry->published;
echo $entry->updated;
foreach($entry->link as $link)
{
echo $link->attributes()->type;
echo $link->attributes()->rel;
}
}

PHP: foreach not forming an array

I do this and it works.
<?php
function load_file($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$xml = simplexml_load_string(curl_exec($ch));
return $xml;
}
$feedurl = 'http://www.astrology.com/horoscopes/daily-extended.rss';
$rss = load_file($feedurl);
$items = array();
$count = 0;
foreach ($rss->channel->item->description as $i => $description)
{
$items[$count++] = $description;
}
echo $items[0];
?>
When I echo $items[1]; it doesn't show the next one in line. Not sure what I did wrong.
Here is an example of your xml:
<channel>
<item>
<description>blah</description>
</item>
<item>
<description>blah1</description>
</item>
<item>
<description>blah2</description>
</item>
<item>
<description>blah3</description>
</item>
</channel>
When you do $rss->channel->item->description you're getting the first item's description.
You need to first loop through the items and then get each description.
e.g.:
$descriptions = array();
foreach($rss->channel->item as $item){
$descriptions[] = $item->description;
// note I don't need the $count variable... if you just use
// [] then it auto increments the array count for you.
}
Hope that helps. Its untested, but should work.

Categories