Iterating arrays and DOM

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
aliasxneo
Forum Contributor
Posts: 136
Joined: Thu Aug 31, 2006 12:01 am

Iterating arrays and DOM

Post by aliasxneo »

Just to clear this up I had an old topic that was asking how to write XML but now that I have a written class and am having problems traversing an array I've decided to make a new topic.

Anyways, essentially I'm trying to iterate through an array of array's (I'm assuming there can be an infinite number of arrays) and create a DOM/XML structure that represents the array in the data. Here's the current class I've written:

Code: Select all

<?php
 
class XMLGen
{
    private $data;
    
    private $xml;
    private $lastEle;
    
    function __construct($data)
    {
        $this->data = $data;
    }
    
    public function toXML()
    {
        $this->xml = new DOMDocument('1.0', 'UTF-8');
        
        $root = $this->xml->createElement("results");
        $this->lastEle = $root;
        $this->iterate($this->data);
        
        $this->xml->appendChild($root);
        
        return $this->xml->saveXML();
    }
    
    private function iterate($array)
    {
        foreach($array as $key => $value)
        {
            print_r($array);
            if (is_numeric($key)) { continue; }
            
            if (is_array($value))
            {       
                $ele = $this->xml->createElement($key);
                $this->lastEle->appendChild($ele);
                $this->lastEle = $ele;
                
                $this->iterate($value);
            } else {
                $this->lastEle->appendChild($this->xml->createElement($key, $value));
            }
        }
    }
}
 
?>
Here is the code I'm using to test this class:

Code: Select all

$data = array("quests" => array("quest1" => array("name" => "test", "id" => "1"), "quest2" => array("name" => "test2", "id" => "2")));
$gen = new XMLGen($data);
echo $gen->toXML();
And then the output:

Code: Select all

<results><quests><quest1><name>test</name><id>1</id><quest2><name>test2</name><id>2</id></quest2></quest1></quests></results>
For the most part it's working, but there's one minor problem. As seen in the XML above somehow the quest2 is getting nested in quest1 when it shouldn't be. From what I understand after it finishes looping through quest1 it's not going back up in the hierarchy (as it should be) but continuing onto quest2 and including it in quest1. I realize this is my fault in the code, but I'm not sure how to go about fixing it.

Any help would be greatly appreciated (since this aspect of the project is due soon). Thanks! :)
aliasxneo
Forum Contributor
Posts: 136
Joined: Thu Aug 31, 2006 12:01 am

Re: Iterating arrays and DOM

Post by aliasxneo »

So can anyone help me with this? Still have the same problem.
hansford
Forum Commoner
Posts: 91
Joined: Mon May 26, 2008 12:38 am

Re: Iterating arrays and DOM

Post by hansford »

I see where the problem is, but don't know how to fix it. Seems you need to build a parent/child array which hold the values of the createdElements() and then iterate through and append them all at once based on their parent elements at the end of the program. the way the program is now it just appends the next array to the last element - so quest1 gets appended to quest2 when its parent is really quests. sorry I don't have a better answer for you.

if (is_array($value))
{
$ele = $this->xml->createElement($key);
$this->lastEle->appendChild($ele);
$this->lastEle = $ele;
dml
Forum Contributor
Posts: 133
Joined: Sat Jan 26, 2008 2:20 pm

Re: Iterating arrays and DOM

Post by dml »

Make lastEle a function parameter instead of a member variable.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: Iterating arrays and DOM

Post by Ambush Commander »

Function parameter would work great. An alternative is setting $this->lastEle = $this->lastEle->parentNode after iterating.
Post Reply