Hope you can help me with my issue...
I have this XML file, which I'm getting the info with the function simplexml_load_file()
:
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<Xiami>
<ArtistID>179</ArtistID>
<ArtistName>Band 1</ArtistName>
<XiamiID>9dl4gN1c745</XiamiID>
<Streaming>246</Streaming>
<Fans>84</Fans>
<TotalComments>1992</TotalComments>
<AllSongs>
<Songs>
<SongID>8ILroS998dc</SongID>
<SongName>Song 1</SongName>
<SongComments>9223</SongComments>
</Songs>
<Songs>
<SongID>8ILLD61a351</SongID>
<SongName>Song 2</SongName>
<SongComments>7221</SongComments>
</Songs>
<Songs>
<SongID>mTnf0L5d6b9</SongID>
<SongName>Song 3</SongName>
<SongComments>21212</SongComments>
</Songs>
<Songs>
<SongID>xOd2YIc7f69</SongID>
<SongName>Song 4</SongName>
<SongComments>422</SongComments>
</Songs>
<Songs>
<SongID>mTmg866314c</SongID>
<SongName>Song 5</SongName>
<SongComments>81211</SongComments>
</Songs>
</AllSongs>
</Xiami>
</rss>
This is the code that I'm using in order to get the data:
<?php
foreach($xml->children() as $Artist) {
$ArtistName = $Artist->ArtistName;
$Streaming = $Artist->Streaming;
$Fans = $Artist->Fans;
$SongsArrays = $Artist->AllSongs;
$SongsCount = $Artist->AllSongs->Song->count();
}
?>
If I print print_r($SongsArrays)
, I'm getting the following array:
SimpleXMLElement Object
(
[Song] => Array
(
[0] => SimpleXMLElement Object
(
[SongID] => 8ILroS998dc
[SongName] => Song 1
[SongComments] => 9223
)
[1] => SimpleXMLElement Object
(
[SongID] => 8ILLD61a351
[SongName] => Song 2
[SongComments] => 7221
)
[2] => SimpleXMLElement Object
(
[SongID] => mTnf0L5d6b9
[SongName] => Song 3
[SongComments] => 21212
)
[3] => SimpleXMLElement Object
(
[SongID] => xOd2YIc7f69
[SongName] => Song 4
[SongComments] => 422
)
[4] => SimpleXMLElement Object
(
[SongID] => mTmg866314c
[SongName] => Song 5
[SongComments] => 81211
)
)
)
If I print the whole array, Imm getting this:
SimpleXMLElement Object
(
[ArtistID] => 179
[ArtistName] => Band 1
[XiamiID] => 9dl4gN1c745
[Streaming] => 246
[Fans] => 84
[AllSongs] => SimpleXMLElement Object
(
[Song] => Array
(
[0] => SimpleXMLElement Object
(
[SongID] => 8ILroS998dc
[SongName] => Song 1
[SongComments] => 9223
)
[1] => SimpleXMLElement Object
(
[SongID] => 8ILLD61a351
[SongName] => Song 2
[SongComments] => 7221
)
[2] => SimpleXMLElement Object
(
[SongID] => mTnf0L5d6b9
[SongName] => Song 3
[SongComments] => 21212
)
[3] => SimpleXMLElement Object
(
[SongID] => xOd2YIc7f69
[SongName] => Song 4
[SongComments] => 422
)
[4] => SimpleXMLElement Object
(
[SongID] => mTmg866314c
[SongName] => Song 5
[SongComments] => 81211
)
)
)
)
The question is:
I've tried almost everything what google and other forums reccomends, but cannot find how to get this data without write a huge code (separating each array and creating a lot of loops)... is there any faster and easy way to do it?
You could use this function to extract the most popular songs for an artist. It uses xpath
to get the Songs
from AllSongs
and then usort
to sort that list by SongComments
descending, finally using array_slice
to return only the 3 most popular songs:
function popular_songs($Artist) {
$Songs = $Artist->xpath('//Songs');
usort($Songs, function ($a, $b) { return $b->SongComments - $a->SongComments; });
return array_slice($Songs, 0, 3);
}
Inside your loop you would call it as:
$PopularSongs = popular_songs($Artist);
If you then print_r($PopularSongs)
you will get (for your sample data)
Array
(
[0] => SimpleXMLElement Object
(
[SongID] => mTmg866314c
[SongName] => Song 5
[SongComments] => 81211
)
[1] => SimpleXMLElement Object
(
[SongID] => mTnf0L5d6b9
[SongName] => Song 3
[SongComments] => 21212
)
[2] => SimpleXMLElement Object
(
[SongID] => 8ILroS998dc
[SongName] => Song 1
[SongComments] => 9223
)
)
To get the total comments per artist, you can use this code, which finds all the SongComment
elements, converts them to integers and sums them:
$TotalComments = array_reduce($Artist->xpath('//SongComments'), function ($c, $v) { return $c + $v; }, 0);
For your sample data, this gives 119289.