以递归方式从xml解析类别,子类别并存储在db中

I have an xml where i have to parse the categories and store them in db.The categories have child categories and child categories have sub child categories.It is like tree structure.I need a recursive function to fetch the sub categories if a category have subcategory.I need to store categoryid,categoryname,parentcategoryid in db.

This is my xml

 <test>
    <categorylist>
    <categoryitem>
    <id>
    <![CDATA[ 47 ]]>
    </id>
    <name>
    <![CDATA[ Homeparties ]]>
    </name>
    </categoryitem>
    <categoryitem>
    <id>
    <![CDATA[ 86 ]]>
    </id>
    <name>
    <![CDATA[ All Products ]]>
    </name>
    </categoryitem>
    <categoryitem>
    <id>
    <![CDATA[ 111 ]]>
    </id>
    <name>
    <![CDATA[ Machines ]]>
    </name>
    <categorylist>
    <categoryitem>
    <id>
    <![CDATA[ 1147 ]]>
    </id>
    <name>
    <![CDATA[ Machine Colours ]]>
    </name>
    <categorylist>
    <categoryitem>
    <id>
    <![CDATA[ 1397 ]]>
    </id>
    <name>
    <![CDATA[ Black ]]>
    </name>
    </categoryitem>
    </categorylist>
    </categoryitem>
    </categorylist>
    </categoryitem>
    </categorylist>
    </test>

store them as category_id category_name parent_category_id

for the above i have tried like this.It is working fine for some levels like upto three levels.suppose if it is n levels,I need a recursive fuction.The below is my code.

if($xml){
                            $this->fetchCategoriesRecursive($xml);
}



      public function fetchCategoriesRecursive($categories)
      {
          foreach($categories->{'categorylist'}->{'categoryitem'} as $category)
                              {
                                    $this->insertCategory($category);

                                    foreach($category->{'categorylist'}->{'categoryitem'} as $category_child)
                                    {
                                          $this->insertCategory($category_child,$category->{'id'});

                                    foreach($category_child->{'categorylist'}->{'categoryitem'} as $category_sub_child)
                                    {
                                          $this->insertCategory($category_sub_child,$category_child->{'id'});

                                    }

                                    }
                              }
      }


public function insertCategory($category,$category_id)
      {
             $category_info=array();
             $category_info = $this->_db->fetchCol("SELECT category_id FROM category_mapping");

            $data = array();
            $data['category_id'] = $category->{'id'};
            $data['category_name'] = $category->{'name'};
                $data['parent_category_id'] = $category_id;

        if(!in_array($data['category_id'],$category_info))
        {
            $this->_db->insert('category_mapping', $data);
        }
      } 

Here is no need for a recursion, you can iterate over all categoryitem elements using Xpath. Each node knows its position inside the DOM. So you can fetch all categoryitem parent elements and use the nearest (the first) one.

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

// iterate all categoryitem elements
foreach ($xpath->evaluate('//categoryitem') as $node) {
  var_dump(
    [
      // fetch the id of the nearest categoryitem element on the ancestor axis
      'parent_id' => $xpath->evaluate('string(ancestor::categoryitem[1]/id)', $node),
      // fetch the id as string
      'id' => $xpath->evaluate('string(id)', $node),
      // fetch the name as string
      'name' => $xpath->evaluate('string(name)', $node),
    ]
  );
}

Output:

array(3) {
  ["parent_id"]=>
  string(0) ""
  ["id"]=>
  string(4) " 47 "
  ["name"]=>
  string(13) " Homeparties "
}
array(3) {
  ["parent_id"]=>
  string(0) ""
  ["id"]=>
  string(4) " 86 "
  ["name"]=>
  string(14) " All Products "
}
array(3) {
  ["parent_id"]=>
  string(0) ""
  ["id"]=>
  string(5) " 111 "
  ["name"]=>
  string(10) " Machines "
}
array(3) {
  ["parent_id"]=>
  string(5) " 111 "
  ["id"]=>
  string(6) " 1147 "
  ["name"]=>
  string(17) " Machine Colours "
}
array(3) {
  ["parent_id"]=>
  string(6) " 1147 "
  ["id"]=>
  string(6) " 1397 "
  ["name"]=>
  string(7) " Black "
}