//原创,可以自由使用,欢迎提出改进意见,
<?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;
}
}
?>