<?php
/**
 * XML数据导入数据库类
 * @author : wanghui([email protected])
 * @create date: 2007-4-25
 */
require_once("PEAR.php");        //PEAR
require_once("conndb.php");       //配置文件(连库)
require_once("DB.php");          //数据库类
require_once('XML/Parser.php');define('XML2DB_CALL_UNDEFINED_FUNC','0001');
define('XML2DB_NO_ROW_ELEMENT','0002');
define('XML2DB_NO_TABLE_NAME','0003');
define('XML2DB_NO_ROW_TAGS','0004');
class XML2DB extends XML_Parser
{
var $_data        = array();   //当前行数据
var $_currTags    = '';        //当前列字段名
var $_currCdata   = '';        //当前列数据
var $_currCnt     = 0;         //当前记录条数
var $_rootElem    = '';        //根元素名
var $_state       = 0;         //解析当前状态(0未开始或已结束,1正在解析)
var $_findRowTags = 0;         //是否找到代表行的tags var $xmlFile    = '';        //要解析的xml文件
var $db         = NULL;      //数据库对象
var $maxCnt     = NULL;      //允许循环的最大条数,默认为全部
var $rowElem    = '';        //代表数据库中行的元素的元素名
var $tableName  = '';        //表名
var $userFunc   = '';      //调用用户数据处理函数的函数名
var $debug      = false;     //除错模式(1每解析一个tags都输出,2解析完代表一行的数据后以数组形式输出)
var $debugInfo  = 'html';    //输出html格式还是shell格式

function XML2DB()
{
parent::XML_Parser();
} function setOptions($options)
{
$availableOptions = array('xmlFile', 'db', 'userFunc', 'rowElem', 'tableName', 'maxCnt', 'debug', 'debugInfo');
foreach($options as $property => $value) 
{
            if(in_array($property, $availableOptions)) 
{
                $this->$property = $value;
            }
        }
$this->rowElem = strtoupper($this->rowElem);
$r = $this->setInputFile($this->xmlFile);
if (PEAR::isError($r))
{
return $r;
}
if ($this->userFunc)
{
if (!function_exists($this->userFunc))
{
return PEAR::RaiseError('调用未定义的函数',XML2DB_CALL_UNDEFINED_FUNC);
}
}
if (!rowElem)
{
return PEAR::RaiseError('未指定行元素名',XML2DB_NO_ROW_ELEMENT);
}
if ($this->debug)
{
if (!$this->db)
{
$this->_output('DataBase Resource is NULL');
}
else
{
if (!$this->tableName)
{
return PEAR::RaiseError('未指定数据库表名',XML2DB_NO_TABLE_NAME);
}
}
}
}

/**
 * handle start element
 *
 * @access private
 * @param  resource  xml parser resource
 * @param  string    name of the element
 * @param  array     attributes
 */
function startHandler($xp, $name, $attribs)
{
if ($this->_state == 0)
{
$this->_state = 1;
$this->_rootElem = $name;
if ($this->debug)
{
$this->_output('Parse Start...');
$this->_output('Root Element:[red]'.$this->_rootElem.'[/red]');
}
}
else
{
switch($name)
{
case $this->rowElem:
if (!$this->_findRowTags)
{
$this->_findRowTags = 1;
if ($this->debug)
{
$this->_output('Find Row Element:[red]'.$this->rowElem.'[/red]');
}
}
$this->_data = array();
break;
default:
$this->_currTags  = $name;
$this->_currCdata = '';
break;
}
}
} /**
  * handle start element
  *
  * @access private
  * @param  resource  xml parser resource
  * @param  string    name of the element
  */
  function endHandler($xp, $name)
  {
switch($name)
{
case $this->_rootElem:
$this->_state = 0;
if (!$this->_findRowTags)
{
$this->_output('[red]Error:['.XML2DB_NO_ROW_TAGS.']未找到代表行的tags:'.$this->rowElem.'[/red]');
}
if (debug)
{
$this->_output("Parse Complete");
}
break;
case $this->rowElem:
   if (!is_null($this->maxCnt) && $this->_currCnt >= $this->maxCnt)
{
return false;
}
if ($this->userFunc)
{
$data = call_user_func($this->userFunc, $this->_data);
}
else
{
$data = $this->_data; 
}
if ($data && $this->debug==2)
{
$this->_output($data,'arr');
}
if ($this->db && $data)
{
$r = $this->db->autoExecute($this->tableName, $data, DB_AUTOQUERY_INSERT);
if (PEAR::isError($r)) 
{
//die($r->getMessage().$r->getUserInfo());
$this->_output("[red]" . $r->getMessage() . '[br]' . $r->getUserInfo() . "[/red]");
}
$this->_currCnt++;
}
break;
default:
if ($this->debug==1)
{
$this->_output("".$this->_currTags."=[red]".$this->_currCdata."[/red]\n");
}
$this->_data[$this->_currTags] = $this->_currCdata;
$this->_currTags  = '';
$this->_currCdata = '';
break;
}
}
  
/**
 * handle character data
 *
 * @access private
 * @param  resource  xml parser resource
 * @param  string    character data
 */
function cdataHandler($xp, $cdata)
{
$this->_currCdata .= $cdata;
}

function _output($info,$isArr='')
{
switch ($this->debugInfo)
{
case 'html':
$info = str_replace('[red]', '<span style="color:red">', $info);
$info = str_replace('[/red]', '</span>', $info);
$info = str_replace('', '<b>', $info);
$info = str_replace('', '</b>', $info);
$info = str_replace('[br]', '<br />', $info);
if ($isArr=='arr')
{
echo '<pre>';
print_r($info) . "\n";
echo '</pre>';
}
else
{
echo $info . "<br>\n";
}
break;
case 'shell':
$info = str_replace('[red]', '', $info);
$info = str_replace('[/red]', '', $info);
$info = str_replace('', '', $info);
$info = str_replace('', '', $info);
$info = str_replace('[br]', "\n", $info);
if ($isArr=='arr')
{
print_r($info) . "\n";
}
else
{
echo $info . "\n";
}
break;
default:
echo $info . "<br>\n";
break;
}
}
}?>