0

I have recently been working with tv_grab_uk_rt which generates a TV guide xml file. I have written a script to convert the XML into an object which I can the loop through and insert into a database. Whilst I have the script working, I came across an issue I was looking to get clarification for.

When putting the XML to an object I get the following:

SimpleXMLElement Object
(
[@attributes] => Array
    (
        [date] => Mon, 23 Dec 2013 04:30:01 GMT
        [source-info-url] => http://www.radiotimes.com
        [source-info-name] => Radio Times XMLTV Service
        [source-data-url] => http://xmltv.radiotimes.com/xmltv/channels.dat
        [generator-info-name] => XMLTV/0.5.61, tv_grab_uk_rt 1.342, 2011/06/19 06:50:36 
        [generator-info-url] => http://www.xmltv.org
    )

[channel] => Array
    (
        [0] => SimpleXMLElement Object
            (
                [@attributes] => Array
                    (
                        [id] => fiver.channel5.co.uk
                    )

                [display-name] => 5*
                [icon] => SimpleXMLElement Object
                    (
                        [@attributes] => Array
                            (
                                [src] => http://www.lyngsat-logo.com/logo/tv/cc/channel5_star.jpg
                            )

                    )

            )
    )
)

Lets say this object is contained within the variable $xml, if I were to do the following:

foreach($xml->channel as $channel)
{
  echo $channel->displayname
}

I realise I would be able to echo the object property of displayname, in this case 5*.

But what happens if I wanted to say echo the src in this case http://www.lyngsat-logo.com/logo/tv/cc/channel5_star.jpg, how would I go about doing this with an object. I can't for example do

foreach($xml->channel as $channel)
{
  echo $channel->icon->@attributes->src
}

With arrays for example you could easily do

foreach($xml['channel'] as $channel)
{
  echo $channel['icon']['@attributes']['src'];
}

But not with objects. Rather than getting into endless loops I found I could convert the object to an array like so

 foreach($xml->channel as $channel)
{
  echo $channel['icon']['@attributes']['src'];
  $channelArray = get_object_vars($channel);
}

Then I can simply access the properties as an array. So my question really is, without converting the object into an array, is there a way to drill into the properties ie

$xml->channel->0->displayname
The Humble Rat
  • 4,586
  • 6
  • 39
  • 73
  • You can access XML attributes within SimpleXML by using array access (`$element['src']`), the `@attribute` is only cosmetic and *not* a property of the object as you have misunderstood it. This is well explained in the PHP Manual: [Basic SimpleXML usage](http://php.net/simplexml.examples-basic) – hakre Dec 24 '13 at 14:00

1 Answers1

1

Each channel is a SimpleXMLElement instance so you can

foreach($xml->channel as $channel)
{
  echo $channel->icon->attributes()->src;
}

When in doubt always start from the official docs.

Sergiu Paraschiv
  • 9,929
  • 5
  • 36
  • 47
  • Ok that makes a lot of sense now for `@attributes` being `attributes()`. Can you possibly detail as well (if channel has more than one element), how would I go about accessing say the second object ie `channel[1]` – The Humble Rat Dec 24 '13 at 12:16
  • Oh, sorry, I was referring to `$channel` inside your `foreach`. Updated the answer. But yes, you can also use `$xml->channel[1]`. – Sergiu Paraschiv Dec 24 '13 at 12:17
  • No problem I found that by doing this `$xml->channel[9]->attributes()->id` I was able to get the desired result. One final question. The `displayname` is actually `display-name` (I changed this for clarity in the question). When I do say `$channel->display-name`, this does not seem to work due to the hyphen in the name. How would I go about this? – The Humble Rat Dec 24 '13 at 12:21
  • You can use `$channel->{'display-name'}`. (http://docs.php.net/manual/en/language.variables.variable.php) – Sergiu Paraschiv Dec 24 '13 at 12:23
  • Excellent. I will be sure to check the docs and I have a book to read on this also. These were just a few things confusing me. Thanks for all you help, this has seriously helped me out, much appreciated. – The Humble Rat Dec 24 '13 at 12:25
  • @TheHumbleRat: You better do so, I left you a link under the question, there is a different (and IMHO better way) to access attributes, and it's well explained in *Basic SimpleXML usage* (linked above). – hakre Dec 24 '13 at 14:02
  • I fail to understand how one syntax could be better than the other. simpleXMLElement variables are not objects or arrays. They are resources and the underlying system allows both syntaxes. IMHO having to diferentiate between numeric keys for child elements and strings for attributes is far worse than separating them with 'children()' and 'attributes()'. Also you must use them if you are dealing with namespaces. – Sergiu Paraschiv Dec 24 '13 at 16:45