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

时间:2014-01-07 11:49:49

标签: php xml

我有一个xml,我必须解析类别并将它们存储在db中。类别有子类别,子类别有子子类。它就像树结构。我需要一个递归函数来获取子类别一个类别有子类别。我需要在db。中存储categoryid,categoryname,parentcategoryid。

这是我的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>

将它们存储为 category_id category_name parent_category_id

对于上面我已经尝试过这样。它在某些级别上工作正常,例如最多三个级别。如果它是n级别,则需要一个递归函数。下面是我的代码。

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);
        }
      } 

1 个答案:

答案 0 :(得分:0)

这里不需要递归,您可以使用Xpath迭代所有categoryitem个元素。每个节点都知道它在DOM中的位置。因此,您可以获取所有categoryitem个父元素并使用最近的(第一个)元素。

$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),
    ]
  );
}

输出:

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 "
}