蒙在股里 发表于 2015-2-4 00:10:19

PHP网页编程之解析xml文档的一个复杂php类

一些真正的强人总会搞出新玩意来丢给你,你不学就落后了,也印证了前人的经验,果然是学无止境啊!xml   //原创,可以自在利用,接待提出改善定见,
<?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;
    }
}
?>
培训的第一阶段,学习的是HTML/CSS/JavaScript基础。

分手快乐 发表于 2015-2-4 09:49:37

我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。

精灵巫婆 发表于 2015-2-4 13:00:34

有位前辈曾经跟我说过,phper 至少要掌握200个函数 编起程序来才能顺畅点,那些不熟悉的函数记不住也要一拿手册就能找到。所以建议新手们没事就看看php的手册(至少array函数和string函数是要记牢的)。

第二个灵魂 发表于 2015-2-5 23:10:44

最后介绍一个代码出错,但是老找不到错误方法,就是 go to wc (囧),出去换换气没准回来就找到错误啦。

莫相离 发表于 2015-2-14 03:04:43

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

愤怒的大鸟 发表于 2015-3-4 04:14:24

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

再现理想 发表于 2015-3-10 07:35:48

说点我烦的低级错误吧,曾经有次插入mysql的时间 弄了300年结果老报错,其实mysql的时间是有限制的,大概是到203X年具体的记不清啦,囧。

灵魂腐蚀 发表于 2015-3-16 09:36:55

微软最近出的新字体“微软雅黑”,虽然是挺漂亮的,不过firefox支持的不是很好,所以能少用还是少用的好。

简单生活 发表于 2015-3-22 22:09:20

在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。

不帅 发表于 2015-3-25 04:10:27

多看优秀程序员编写的代码,仔细理解他们解决问题的方法,对自身有很大的帮助。

蒙在股里 发表于 2015-4-9 15:04:41

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

小妖女 发表于 2015-4-15 23:05:26

我还是推荐用firefox ,配上firebug 插件调试js能省下不受时间。谷歌的浏览器最好也不少用,因为谷歌的大侠们实在是太天才啦,把一些原来的js代码加了一些特效。

冷月葬花魂 发表于 2015-4-24 04:41:31

环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。

深爱那片海 发表于 2015-5-1 22:12:05

装在C盘下面可以利用windows的ghost功能可以还原回来(顺便当做是重转啦),当然啦我的编译目录要放在别的盘下,不然自己的劳动成果就悲剧啦。

只想知道 发表于 2015-5-4 10:16:12

写的比较杂,因为我也是个新手,不当至于大家多多指正。

飘灵儿 发表于 2015-5-9 09:50:51

曾经犯过一个很低级的错误,我在文件命名的时候用了一个横线\\\\\\\'-\\\\\\\' 号,结果找了好几个小时的错误,事实是命名的时候 是不能用横线 \\\\\\\'-\\\\\\\' 的,应该用的是下划线\\\\\\\'_\\\\\\\' ;

乐观 发表于 2015-6-26 13:53:52

再就是混迹于论坛啦,咱们的phpchina的论坛就很强大,提出的问题一般都是有达人去解答的,以前的帖子也要多看看也能学到不少前辈们的经验。别的不错的论坛例如php100,javaeye也是很不错的。

山那边是海 发表于 2015-6-27 19:06:46

我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。

admin 发表于 2015-7-2 05:55:47

基础有没有对学习php没有太大区别,关键是兴趣。

仓酷云 发表于 2015-7-2 23:52:14

作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。
页: [1]
查看完整版本: PHP网页编程之解析xml文档的一个复杂php类