Search code examples
phparraysassociative-arraykodi

php reading kodi/xbmc movie nfo files


I am working on a php script to parse the movie nfo and tv nfo files that kodi generates/uses.

However I have problems with getting some of the children properties (not sure if this is the correct term.)

So far I am using simplexml, to read the nfo file, and gather the data.

However I struggle getting the ratings and rating subset of data.

I can't figure out the right context to get the specific values I want/need.

<ratings>
<rating default="false" max="100" name="metacritic">
  <value>46.0</value>
  <votes>0</votes>
</rating>
<rating default="false" max="10" name="themoviedb">
  <value>6.6</value>
  <votes>1175</votes>
</rating>
<rating default="false" max="100" name="tomatometerallcritics">
  <value>56.0</value>
  <votes>36</votes>
</rating>
<rating default="false" max="10" name="tomatometeravgcritics">
  <value>4.5</value>
  <votes>36</votes>
</rating>
<rating default="true" max="10" name="imdb">
  <value>6.6</value>
  <votes>91750</votes>
</rating>
<rating default="false" max="10" name="trakt">
  <value>7.2</value>
  <votes>2629</votes>
</rating>

When I get the results, and parse them and just get this dump of an array, and I can't figure out how to grab the specific data I want.

Array ( 
    [rating] => Array ( 
        [0] => Array ( 
            [@attributes] => Array ( 
                [default] => false 
                [max] => 10 
                [name] => themoviedb 
            ) 
            [value] => 7.2 
            [votes] => 3716 
        ) 
        [1] => Array ( 
            [@attributes] => Array ( 
                [default] => false 
                [max] => 100 
                [name] => tomatometerallcritics 
            ) 
            [value] => 94.0 
            [votes] => 219 
        ) 
        [2] => Array ( 
            [@attributes] => Array ( 
                [default] => true 
                [max] => 10 
                [name] => imdb 
            ) 
            [value] => 7.3 
            [votes] => 130474 
        ) 
        [3] => Array ( 
            [@attributes] => Array ( 
                [default] => false 
                [max] => 100 
                [name] => metacritic 
            ) 
            [value] => 77.0 
            [votes] => 0 
        ) 
        [4] => Array ( [@attributes] => Array ( [default] => false [max] => 10 [name] => tomatometeravgcritics ) [value] => 7.9 [votes] => 219 ) 
        [5] => Array ( [@attributes] => Array ( [default] => false [max] => 10 [name] => trakt ) [value] => 7.5 [votes] => 8201 ) ) )

Here is the code I use in a function to grab and parse the nfo file.

    // Read entire file into string
        $xmlfile = file_get_contents($nfo);
          
        // Convert xml string into an object
        $new = simplexml_load_string($xmlfile);
          
        // Convert into json
        $con = json_encode($new);
          
        // Convert into associative array
        $newArr = json_decode($con, true);

I have tried all kinds of loops, and those either error out, or give me nothing. Array_keys, array_values, I am clearly not grokking the correct way to grab those fields in the nfo file.

Any suggestions are welcome.

[Edit] So my desired output would be like: Name of Rating, Votes.

Since the variety of ratings in each movie nfo file varies, just to be able to get whichever ratings were there, and what votes they had for the selected movie.

[Edit] Finally got the answer to all the data I want on each rating. I had to make a few slight changes to the suggested code, which really helped me out a lot!

// loop thru each rating
foreach($movie['rating'] as $a){

    // loop thru each array length
    for($i = 0; $i < count($a); $i++) {

        // get all the properties of the rating
        foreach($a[$i]['@attributes'] as $name => $attrib){

            echo 'Name: ['.$name.']<Br/>';
            echo 'Value: ['.$attrib.']<br/>';
            echo 'Votes: ['.$a[$i]['value'].']<br/';
            echo '<br/>';

        }
    }
}   

Which gave me the output of:

Name: [name] Value: [imdb] Votes: [6.4]

It is a longer list but now I can get each rating and it's values/attributes.

Thank you so much!


Solution

  • $newArr = [
        
            'rating'=> [
                    ['@attributes'=>['default'=>'false','max'=>10,'name'=>'The Movie'], 'value'=>1, 'votes'=>5],
                    ['@attributes'=>['default'=>'false','max'=>100,'name'=>'The Other Movie'], 'value'=>1, 'votes'=>5]
                    ]
    ];
    
    foreach($newArr['rating'] as $a){
        foreach($a['@attributes'] as $name => $attrib){
            echo 'attributes name = >' . $name . '< and its value is = >' . $attrib . ' and votes are = >' . $a['votes']. "<\n";
        }
    }
    

    And the result

    attributes name = >default< and its value is = >false and votes are = >5<
    attributes name = >max< and its value is = >10 and votes are = >5<
    attributes name = >name< and its value is = >The Movie and votes are = >5<
    attributes name = >default< and its value is = >false and votes are = >15<
    attributes name = >max< and its value is = >100 and votes are = >15<
    attributes name = >name< and its value is = >The Other Movie and votes are = >15<
    

    Alternatively you can just

    $newArr = [
        
            'rating'=> [
                    ['@attributes'=>['default'=>'false','max'=>10,'name'=>'The Movie'], 'value'=>1, 'votes'=>5],
                    ['@attributes'=>['default'=>'false','max'=>100,'name'=>'The Other Movie'], 'value'=>1, 'votes'=>15]
                    ]
    ];
    
    foreach($newArr['rating'] as $a){
        echo 'max = ' . $a['@attributes']['max'].PHP_EOL;
        echo 'name = ' . $a['@attributes']['name'].PHP_EOL;
        // also easy access to votes and 
        echo 'Votes = ' . $a['votes'] . PHP_EOL;            
    }
    

    Giving

    max = 10
    name = The Movie
    Votes = 5
    max = 100
    name = The Other Movie
    Votes = 15