首页 > 开发 > PHP > 正文

解析xml文档的一个简单php类

2024-05-04 22:59:50
字体:
来源:转载
供稿:网友

//原创,可以自由使用,欢迎提出改进意见,

<?php
//xml中的元素
class xmltag
{
 var $parent;//父节点
 var $child;//子节点
 var $attribute;//本节点属性
 var $data;//本节点数据
 var $tagname;//本节点名称
 var $depth;//本节点的深度,根节点为1
 function xmltag($tag='')
 {
  $this->attribute = array();
  $this->child = array();
  $this->depth = 0;
  $this->parent = null;
  $this->data = '';
  $this->tagname = $tag;
 }
 function settagname($tag)
 {
  $this->tagname = $tag;
 }
 function setparent(&$parent)
 {
  $this->parent = &$parent;
 }
 function setattribute($name,$value)
 {
  $this->attribute[$name] = $value;
 }
 function appendchild(&$child)
 {
  $i = count($this->child);
  $this->child[$i] = &$child;
 }
 function setdata($data)
 {
  $this->data= $data;
 }
 function getattr()
 {
  return $this->attribute;
 }
 function getproperty($name)
 {
  return $this->attribute[$name];
 }
 function getdata()
 {
  return $this->data;
 }
 function getparent()
 {
  return $this->parent;
 }
 function getchild()
 {
  return $this->child;
 }
 function getchildbyname($name)
 {
  $total = count($this->child);
  for($i=0;$i<$total;$i++)
  {
   if($this->child[$i]->attribute['name'] == $name)
   {
    return $this->child[$i];
   }
  }
  return null;
 }
 //获取某个tag节点
    function getelementsbytagname($tag)
    {
     $vector = array();
     $tree = &$this;
     $this->_getelementbytagname($tree,$tag,$vector);
     return $vector;
    }
    function _getelementbytagname($tree,$tag,&$vector)
    {
     if($tree->tagname == $tag) array_push($vector,$tree);
     $total = count($tree->child);
     for($i = 0; $i < $total;$i++)
      $this->_getelementbytagname($tree->child[$i],$tag,$vector);
    }
}
//xml文档解析
class xmldoc
{
 var $parser;//xml解析指针
 var $xmltree;//生成的xml树
 var $xmlfile;//将要解析的xml文档
 var $xmldata;//将要解析的xml数据
 var $error;//错误信息
 var $nowtag;//当前指向的节点
 var $treedata;//遍历生成的xml树等到的数据
 var $maxdepth;//本树最大的深度
 var $encode;//xml文档的编码方式
 var $chs;//字符转换
 function xmldoc()
 {
  //采用默认的iso-8859-1
  $this->parser = xml_parser_create();
  xml_parser_set_option($this->parser,xml_option_case_folding,0);
  xml_set_object($this->parser,&$this);
  xml_set_element_handler($this->parser,'_startelement','_endelement');
  xml_set_character_data_handler($this->parser,'_cdata');
  $this->stack = array();
  $this->xmltree = null;
  $this->nowtag = null;
  $this->maxdepth = 0;
 }
 function loadfromfile($file)
 {
  $this->xmlfile = fopen($file,'r');
  if(!$this->xmlfile)
  {
   $this->error = '不能打开xml文件';
   return false;
  }
  $this->xmldata = '';
  $this->treedata = '';
  return true;
 }
 function setxmldata($data)
 {
  if($this->xmlfile) fclose($this->xmlfile);
  $this->xmldata = $data;
  $this->treedata = '';
 }
 //给树添加一个新的节点
 function appendchild(&$child)
 {
  if($this->xmltree == null)
  {
   $child->depth = 1;
   $this->xmltree = &$child;
   $this->nowtag = &$this->xmltree;
  }
  else
  {
   $i = count($this->nowtag->child);
   $this->nowtag->child[$i] = &$child;
            $child->parent = &$this->nowtag;
   $child->depth = $this->nowtag->depth+1;
   unset($this->nowtag);
   $this->nowtag = &$child;
  }
  $this->maxdepth = ($this->maxdepth < $this->nowtag->depth)?$this->nowtag->depth:$this->maxdepth;
 }

 //产生一个新的节点
 function &createelement($tag)
 {
  $element = new xmltag($tag);
  return $element;
 }
 function _startelement($parser,$element,$attribute)
 {
  $tag = new xmltag();
  $tag->tagname = $element;
  $tag->attribute = $attribute;
  if($this->xmltree == null)
  {
   $tag->parent = null;
   $tag->depth = 1;
   $this->xmltree = &$tag;
   $this->nowtag = &$tag;
  }
  else
  {
   $i = count($this->nowtag->child);
   $this->nowtag->child[$i] = &$tag;
   $tag->parent = &$this->nowtag;
   $tag->depth = $this->nowtag->depth+1;
   unset($this->nowtag);
   $this->nowtag = &$tag;
  }
  $this->maxdepth = ($this->maxdepth < $this->nowtag->depth)?$this->nowtag->depth:$this->maxdepth;
 }
 function _cdata($paraser,$data)
 {
  $this->nowtag->data = $data;
 }
 function _endelement($parser,$element)
 {
  $parent = &$this->nowtag->parent;
  unset($this->nowtag);
  $this->nowtag = &$parent;
 }
 //开始解析xml文档
 function parse()
 {
  if($this->xmlfile)
  {
   $this->xmldata = '';
   while(!feof($this->xmlfile))
   {
    $this->xmldata .= fread($this->xmlfile,4096);
   }
  }
  fclose($this->xmlfile);
  if($this->xmldata)
  {
   //$this->judgeencode();
   if (!xml_parse($this->parser, $this->xmldata))
   {
    $code = xml_get_error_code($this->parser);
    $col = xml_get_current_column_number($this->parser);
    $line = xml_get_current_line_number($this->parser);
          $this->error = "xml error: $col at line $line:".xml_error_string($code);
          return false;
   }
  }
  xml_parser_free($this->parser);
  return true;
    }
    //确定编码方式
    function judgeencode()
    {
     $start = strpos($this->xmldata,'<?xml');
     $end = strpos($this->xmldata,'>');
     $str = substr($this->xmldata,$start,$end-$start);
     $pos = strpos($str,'encoding');
     if($pos !== false)
     {
      $str = substr($str,$pos);
      $pos = strpos($str,'=');
      $str = substr($str,$pos+1);
      $pos = 0;
      while(empty($str[$pos])) $pos++;
      $this->encode = '';
      while(!empty($str[$pos]) && $str[$pos] != '?')
      {
       if($str[$pos] != '"' && $str[$pos] != "'")
        $this->encode .= $str[$pos];
       $pos++;
      }
     }
     $this->chs = new chinese('utf-8',$this->encode);
    }

    //根据节点名称修改某个节点的值
    function changevaluebyname($name,$name,$value)
    {
     return $this->_changevaluebyname($this->xmltree,$name,$value);
    }
    function _changevaluebyname($tree,$name,$value)
    {
     if(is_array($tree->attribute))
     {
      while (list($k,$v) = each($tree->attribute))
      {
       if($k = 'name' && $v = $name)
       {
        $tree->data = $value;
        return true;
       }
      }
     }
     $total = count($tree->child);
     for($i = 0;$i<$total;$i++)
     {
      $result = $this->_changevaluebyname($tree->child[$i],$name,$value);
      if($result == true) break;
     }
     return $result;
    }

    //根据节点名称修改树中某个节点的属性
    function changeattrbyname($name,$attr,$value)
    {
     return $this->_changeattrbyname($this->xmltree,$name,$attr,$value);
    }
    function _changeattrbyname(&$tree,$name,$attr,$value)
    {
     if(is_array($tree->attribute))
     {
      while(list($k,$v) = each($tree->atttibute))
      {
       if($k == 'name' && $v == $name)
       {
        $tree->attribute[$attr] = $value;
        return true;
       }
      }
     }
     $total = count($tree->child);
     for($i = 0;$i<$total;$i++)
     {
      $result = $this->_changeattrbyname($tree->child[$i],$name,$attr,$value);
      if($result == true) break;
     }
     return $result;
    }
    //获取根节点
    function getdocumentelement()
    {
     return $this->xmltree;
    }
    //遍历生成的xml树,重新生成xml文档
    function walktree()
    {
     $this->treedata = '';
     $this->_walktree($this->xmltree);
     return $this->treedata;
    }
     //递归遍历
    function _walktree($tree)
    {
     $this->treedata .= '<'.$tree->tagname.' ';
     if(is_array($tree->attribute))
     {
      while(list($key,$value) = each($tree->attribute))
      {
       $this->treedata .="$key=/"$value/" ";
      }
     }
     $this->treedata .= '>'.$tree->data;
     $total = count($tree->child);
     for($i=0;$i<$total;$i++)
     {
      $this->_walktree($tree->child[$i]);
     }
     $this->treedata .= '</'.$tree->tagname.">/n";
    }
    //获取错误信息
    function geterror()
    {
     return $this->error;
    }
    //获取树的最大深度
    function getmaxdepth()
    {
     return $this->maxdepth;
    }
    //将xml树写入xml文件
    function writetofile($file,$head='')
    {
     $fp = fopen($file,'w');
     if(!$fp)
     {
      $this->error = '无法打开写入文件';
      return false;
     }
     if(empty($this->treedata)) $this->walktree();
     $head = empty($head)?'<?xml version="1.0" standalone="yes" encoding="gb2312"?>':$head;
     fwrite($fp,$head);
     fwrite($fp,$this->treedata);
     fclose($fp);
     return true;
    }
}
?>

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表