2006/02/28

code:使用php构建的xml分析器 (基础版)

使用php构建的xml分析器 (基础版) 
tags:php,xml,parser,code,fallseir
author:fallseir.lee : http://fallseir.livejournal.com

<?php
$p =& new simplexmlparser();
$p->parse ('/var/www/html/tests/wellformed/sanitize/item_xhtml_body_style.xml');
echo $p->tosimplexml();
//print_r($p->document);
//print_r($p->stack);
?>

<?php class simplexmlparser
{
//记录当前处理队列 var $stack=array(); //root树 var $document=array("namespaces" =>array()); //parser var $xml_parser; //构造函数 function __construct() { $this->xml_parser = xml_parser_create(); xml_set_object($this->xml_parser, $this); xml_set_character_data_handler($this->xml_parser , 'c_data_Handler');
xml_set_element_handler ($this->xml_parser, "start_tag_Handler" ,"end_tag_Handler"); } //处理开始标记 function start_tag_Handler($parser,$tag ,$attrs) { $t=$tag; $ns=null; $atts=array(); //处理命名空间 foreach($attrs as $name=>$value) { if(eregi ( "^xmlns:^xmlns$", $name)){
//取得命名空间的缩写 if(strpos( $name,':')) { list($temp, $name)=split(':' ,$name,2); }else { $name=null; $uncount=0;
foreach($this->document["namespaces" ] as $n=>$v ) { if(strpos( $n,'#')) { $c=str_replace('#' ,''); if($uncount<(int )$c) { $uncount=$c; } } if($value==$v ) { $name=$n; } } //创建默认缩写 if($name===null) { $name="#".($uncount +1); } $ns=$name; } //添加名称空间 if(!array_key_exists( $name,$this->document["namespaces" ])) { $this->document["namespaces"][ $name]=$value; } }else { $atts[$name]= $value; } } //获取当前的名称控件缩写 if ( strpos( $t, ':' ) ) {
list($ns, $t ) = split( ':', $t, 2);
}
//if($t==""){echo "$tag is null";return;} $current=array("name"=> $t,"attributes"=>$atts, "nodes"=>array()); if($ns===null and count ($this->stack)>0) { $ns=$this->stack[count ($this->stack)-1][ "namespace"]; } $current["namespace"]= $ns;
array_push($this->stack ,$current); } //处理内容数据 function c_data_Handler($parser,$data ) { $current=$this->stack[count ($this->stack)-1]; $current["nodes"][]= $data; $this->stack[count( $this->stack)-1]=$current ; } //处理结束标记 function end_tag_Handler($parser,$tag ) { $current=array_pop($this->stack ); if(count( $this->stack)!=0) { $parent=$this->stack[count ($this->stack)-1]; $parent["nodes"][ $current["name"]]=$current ; $this->stack[count( $this->stack)-1]=$parent ; }else { $this->document["root"]= $current; } } function tosimplexml() { $xmlstr= "<?xml version=\" 1.0\" encoding=\" utf-8\"?>"; $xmlstr.= $this->randernode($this ->document["root"],$this->document ["namespaces"],"" ,true); return $xmlstr; } /* * node 处理的节点 * ns 名称空间表 * pns 父节点的前缀 * isroot 是否是根节点 */ function randernode($node,$ns= null,$pns="", $isroot=false) { $name=strtolower($node ['name']); //输出默认命名空间 $namespace=null; $isdefns=false; if(ereg( "^#",$node['namespace' ])) { $namespace="xmlns=\"" .$ns[$node[ 'namespace']]."\"" ; $isdefns=true; } $prx=$node['namespace' ]; //判断是否继承了名称空间 if($pns!=$prx and (!$isdefns)) { $name=strtolower(" $prx:$name"); }else if($pns== $prx and $isdefns) { $namespace=null; } $xmlstr="<{$name} " ; if($namespace!=null) { $xmlstr.=$namespace." "; } $xmlstr.=$this->randerattribute($node ["attributes"]); if(ns!==null and $isroot) { $xmlstr.=$this->randernamespace($ns ); } $xmlstr.=">"; $xmlstr.=$this->randernodes($node ["nodes"],$ns ,$prx); $xmlstr.="</{$name}>" ; return $xmlstr;
}
function randernamespace ($ns) { $xmlstr=""; if($ns!==null) { foreach($ns as $n=>$v) { if(!ereg( "#",$n)) { $xmlstr.=strtolower($n )."=\"$v\" "; } } } return $xmlstr; } function randerattribute($attrs) { $xmlstr=""; foreach($attrs as $n=>$v) { $xmlstr.= strtolower($n )."=\"$v\" "; } return $xmlstr; } function randernodes($nodes,$ns ,$prx) { $xmlstr=""; foreach($nodes as $n=>$v) { if(is_array( $v)) { $xmlstr.= $this->randernode($v ,$ns,$prx ); }else { $xmlstr.= $v ; } } return $xmlstr; } //测试 function parse($path){
if (!($fp = fopen ($path, "r"))) {
die("Cannot open XML data file: $path "); return false; } while ($data = fread ($fp, 4096)) {
if (!xml_parse($this->xml_parser , $data, feof( $fp))) {
die(sprintf ("XML error: %s at line %d", xml_error_string(xml_get_error_code ($this->xml_parser)), xml_get_current_line_number($this->xml_parser ))); xml_parser_free($this->xml_parser ); } } fclose($fp); return true; } } ?>


--
[:p] --飞扬.轻狂 [fallseir.lee]
http://fallseir.livejournal.com
http://feed.feedsky.com/fallseir

没有评论: