zen of coding

Array from XML in CakePHP

Update (9/9/2008): Since the writing of this post, there is now a nicer way to handle this, which David Persson kindly pointed out:

$Xml = new Xml($rawXML);
$Xml->toArray();

For historical reference and if you don’t have the latest and greatest CakePHP core, here’s the “old method”…

On IRC gwoo posted a neat trick to convert an XML string into an array.
I thought that it definitely deserves to be shared with everyone…

Behold:
$myArray = Set::reverse(new Xml(… your XML here…));

Pretty cool.

P.S. Be sure to include: uses(‘Xml’);

  • I thanks a lot for this example, I need this code. My question:
    Is this code quickly? I talk about performance…
    I going to test this code, thanks a lot.

  • teknoid

    @Webmaster Mexico

    Unfortunately, I don’t have any information regarding its performance. Generally speaking, this is unlikely to become a bottleneck in your application…

  • Pingback: CakePHP1.2 で XML を配列として扱う方法 | Sun Limited Mt.()

  • elkin

    I got simple cuestion, there is a way for get the xml file from the local disk ?

  • teknoid

    @elkin

    Yeah, take a look at the File class:
    http://api.cakephp.org/class_file.html

  • elkin

    Nice.. but i’m having troubles with the xml function :

    Fatal error: Class ‘Xml’ not found in /var/webapps/cake/app/controllers/anuncios_controller.php on line 10

    i’m newbie on this.. (2 days working with cake in fact)..

    the code:

    function index() {
    Uses(‘Xml’);
    $this->Anuncio->recursive = 0;
    $this->set(‘anuncios’, $this->Anuncio->findAll());
    $myArray = Set::reverse(new xml(‘the xml goes here’));

  • teknoid

    @elkin

    This class is only available in CakePHP 1.2+
    Please be sure that you are using that version.

    Also if you have any questions, join cake’s friendly IRC channel: #cakephp on irc.freenode.net
    irc://irc.freenode.net/cakephp

  • elkin

    yup… i’m using cake_1.2.0.7125-rc1 .. that’s why i’m totally confused. .. :p

  • Christher

    Thank you. This realy helpt me with my language component.

  • Jeff

    I have a question. If I have a simpleXML object in my model, should I convert it to arrays before sending it back to my controller (then send arrays to my view) or just send my simpleXML objects around in my MVC? I think this is more of a good practice question. My thinking is to send my simpleXML objects around and save the extra step of conversion. Thank you for your help.

  • teknoid

    @Jeff

    If your goal is to pass some data for the view, it’s probably “more cake” to get the array of data and use $this->set().

  • Jeff

    @teknoid: Thank you very much for your input. What I like about conversion into array is the flexibility of creating my own array struction. My only concern with this is the performance hit looping to parse the XML data and pushing it into my array. I think right now I’m leaning towards converting to array.

  • teknoid

    @Jeff

    No problem.

    I’m not sure about why you’d need to do a loop, Set::reverse() will convert your object into an array in one go.

    Maybe I misunderstood what the actual problem was…

  • Jeff

    @teknoid: Ya, if I was to convert my XML to array, I would like to build it in the structure I want it so I can easily get information out of the array and maybe do more processing. Thank you again.

  • majna

    XML class usage problems:
    Example:
    App::import(‘Core’, array(‘Xml’));

    $data= Set::reverse(new XML(‘path to xml file’));

    $data now contains cake-like arrays.
    I found problem in Set::reverse()
    when converting object (xml object) to arrays,
    it removes array index key if there is only one child, like this:
    Users[0][‘name’] will become Users[‘name’], so have additional conditions in view…
    If you have data in xml, you excepts the same format after Set class processing.
    This may be convenient for internal cake methods like model methods,
    but for other usage it is confusing.
    maybe i could open ticket.damn

  • teknoid

    @majna

    Be sure to provide a test case, if you do open a ticket for this. It will help developers to address it sooner and more efficiently.

  • David Persson

    I’ve got the same problem like majna. This way you’ve got to do a lot of postprocessing. By the way instead of using Set::reverse(new Xml($rawXml)); you can use $Xml = new Xml($rawXml); $Xml->toArray(); you’ll get the same results as far as I can see.

  • teknoid

    @David Persson

    Thanks, I’ve added this method to the post as well.

  • Hi,

    Maybe will be good idea conecting this post with this: http://teknoid.wordpress.com/2008/05/05/use-app-controller-to-keep-static-list-data/ and to have all “countries” in an XML file.

    Cheers,
    faemino

  • teknoid

    @faemino

    In that case it would be better to have a transformer method that would return the data in any format you need, so you could have $this->getListXml() or $this->getListJson(), or alternatively $this->getList(‘xml’); … etc., but either approach would simply look up and convert the data from a single array source.

%d bloggers like this: