今天在PHP4环境下重新写一个接口程序,需要大量分析解析XML,PHP的xml_parse_into_struct()函数不能直接生成便于使用的数组,而SimpleXML扩展在PHP5中才支持,于是逛逛搜索引擎,在老外的网站上找到了一个不错的PHP XML操作类。
一、用法举例:
1、将XML文件解释成便于使用的数组:
view plaincopy to clipboardprint?
- <?php ??
-
include('xml.php');??????
-
$xml?=?file_get_contents('data.xml');??????
-
??
-
$data=XML_unserialize($xml); ??
-
echo?'<pre>'; ??
-
print_r($data); ??
-
echo?'</pre>'; ??
- ?>??
data.xml文件:
view plaincopy to clipboardprint?
- <?xml?version="1.0"?encoding="GBK"?>??
-
<video>??
-
<upload>??
-
<videoid>998</videoid>??
-
<name><![CDATA[回忆未来]]></name>??
-
<memo><![CDATA[def]]></memo>??
-
<up_userid>11317</up_userid>??
-
</upload>??
-
</video>??
利用该XML操作类生成的对应数组(汉字编码:UTF-8):
view plaincopy to clipboardprint?
- Array ??
- ( ??
-
????[video]?=>?Array ??
- ????????( ??
-
????????????[upload]?=>?Array ??
- ????????????????( ??
-
????????????????????[videoid]?=>?998 ??
-
????????????????????[name]?=>?回忆未来 ??
-
????????????????????[memo]?=>?def ??
-
????????????????????[up_userid]?=>?11317 ??
- ????????????????) ??
- ??
- ????????) ??
- ??
- )??
2、将数组转换成XML文件:
view plaincopy to clipboardprint?
- <?php ??
-
include('xml.php');??
-
$xml?=?XML_serialize($data); ??
- ?>??
二、PHP XML操作类源代码:
view plaincopy to clipboardprint?
- <?php? ??
- ###################################################################################? ??
- #? ??
- #?XML?Library,?by?Keith?Devens,?version?1.2b? ??
-
#?<a?href="http://keithdevens.com/software/phpxml"?target="_blank">http://keithdevens.com/software/phpxml</a>? ??
- #? ??
- #?This?code?is?Open?Source,?released?under?terms?similar?to?the?Artistic?License.? ??
-
#?Read?the?license?at?<a?href="http://keithdevens.com/software/license"?target="_blank">http://keithdevens.com/software/license</a>? ??
- #? ??
- ###################################################################################? ??
- ??
- ###################################################################################? ??
-
#?XML_unserialize:?takes?raw?XML?as?a?parameter?(a?string)? ??
-
#?and?returns?an?equivalent?PHP?data?structure? ??
- ###################################################################################? ??
-
function?&?XML_unserialize(&$xml){? ??
-
????$xml_parser?=?&new?XML();? ??
-
????$data?=?&$xml_parser->parse($xml);? ??
-
????$xml_parser->destruct();? ??
-
????return?$data;? ??
- }? ??
- ###################################################################################? ??
- #?XML_serialize:?serializes?any?PHP?data?structure?into?XML? ??
-
#?Takes?one?parameter:?the?data?to?serialize.?Must?be?an?array.? ??
- ###################################################################################? ??
-
function?&?XML_serialize(&$data,?$level?=?0,?$prior_key?=?NULL){? ??
-
????if($level?==?0){?ob_start();?echo?'<?xml?version="1.0"??>',"\n";?}? ??
-
????while(list($key,?$value)?=?each($data))? ??
-
????????if(!strpos($key,?'?attr'))?#if?it's?not?an?attribute? ?
- ????????????#we?don't?treat?attributes?by?themselves,?so?for?an?emptyempty?element? ??
- ????????????#?that?has?attributes?you?still?need?to?set?the?element?to?NULL? ??
- ??
-
????????????if(is_array($value)?and?array_key_exists(0,?$value)){? ??
-
????????????????XML_serialize($value,?$level,?$key);? ??
-
????????????}else{? ??
-
????????????????$tag?=?$prior_key???$prior_key?:?$key;? ??
-
????????????????echo?str_repeat("\t",?$level),'<',$tag;? ??
-
????????????????if(array_key_exists("$key?attr",?$data)){?#if?there's?an?attribute?for?this?element? ?
- ????????????????????while(list($attr_name,?$attr_value)?=?each($data["$key?attr"]))? ?
- ????????????????????????echo?'?',$attr_name,'="',htmlspecialchars($attr_value),'"';? ?
- ????????????????????reset($data["$key?attr"]);? ?
- ????????????????}? ?
- ?
- ????????????????if(is_null($value))?echo?"?/>\n";? ?
- ????????????????elseif(!is_array($value))?echo?'>',htmlspecialchars($value),"</$tag>\n";? ?
- ????????????????else?echo?">\n",XML_serialize($value,?$level+1),str_repeat("\t",?$level),"</$tag>\n";? ?
- ????????????}? ?
- ????reset($data);? ?
- ????if($level?==?0){?$str?=?&ob_get_contents();?ob_end_clean();?return?$str;?}? ?
- }? ?
- ###################################################################################? ?
- #?XML?class:?utility?class?to?be?used?with?PHP's?XML?handling?functions? ??
- ###################################################################################? ??
-
class?XML{? ??
-
????var?$parser;???#a?reference?to?the?XML?parser? ??
-
????var?$document;?#the?entire?XML?structure?built?up?so?far? ??
-
????var?$parent;???#a?pointer?to?the?current?parent?-?the?parent?will?be?an?array? ??
-
????var?$stack;????#a?stack?of?the?most?recent?parent?at?each?nesting?level? ??
-
????var?$last_opened_tag;?#keeps?track?of?the?last?tag?opened.? ??
- ??
-
????function?XML(){? ??
-
?????????$this->parser?=?&xml_parser_create();? ??
-
????????xml_parser_set_option(&$this->parser,?XML_OPTION_CASE_FOLDING,?false);? ??
-
????????xml_set_object(&$this->parser,?&$this);? ??
-
????????xml_set_element_handler(&$this->parser,?'open','close');? ??
-
????????xml_set_character_data_handler(&$this->parser,?'data');? ??
- ????}? ??
-
????function?destruct(){?xml_parser_free(&$this->parser);?}? ??
-
????function?&?parse(&$data){? ??
-
????????$this->document?=?array();? ??
-
????????$this->stack????=?array();? ??
-
????????$this->parent???=?&$this->document;? ??
-
????????return?xml_parse(&$this->parser,?&$data,?true)???$this->document?:?NULL;? ??
- ????}? ??
-
????function?open(&$parser,?$tag,?$attributes){? ??
-
????????$this->data?=?'';?#stores?temporary?cdata? ??
-
????????$this->last_opened_tag?=?$tag;? ??
-
????????if(is_array($this->parent)?and?array_key_exists($tag,$this->parent)){?#if?you've?seen?this?tag?before? ?
- ????????????if(is_array($this->parent[$tag])?and?array_key_exists(0,$this->parent[$tag])){?#if?the?keys?are?numeric? ?
- ????????????????#this?is?the?third?or?later?instance?of?$tag?we've?come?across? ??
-
????????????????$key?=?count_numeric_items($this->parent[$tag]);? ??
-
????????????}else{? ??
-
????????????????#this?is?the?second?instance?of?$tag?that?we've?seen.?shift?around? ?
- ????????????????if(array_key_exists("$tag?attr",$this->parent)){? ?
- ????????????????????$arr?=?array('0?attr'=>&$this->parent["$tag?attr"],?&$this->parent[$tag]);? ?
- ????????????????????unset($this->parent["$tag?attr"]);? ?
- ????????????????}else{? ?
- ????????????????????$arr?=?array(&$this->parent[$tag]);? ?
- ????????????????}? ?
- ????????????????$this->parent[$tag]?=?&$arr;? ?
- ????????????????$key?=?1;? ?
- ????????????}? ?
- ????????????$this->parent?=?&$this->parent[$tag];? ?
- ????????}else{? ?
- ????????????$key?=?$tag;? ?
- ????????}? ?
- ????????if($attributes)?$this->parent["$key?attr"]?=?$attributes;? ?
- ????????$this->parent??=?&$this->parent[$key];? ?
- ????????$this->stack[]?=?&$this->parent;? ?
- ????}? ?
- ????function?data(&$parser,?$data){? ?
- ????????if($this->last_opened_tag?!=?NULL)?#you?don't?need?to?store?whitespace?in?between?tags? ??
-
????????????$this->data?.=?$data;? ??
- ????}? ??
-
????function?close(&$parser,?$tag){? ??
-
????????if($this->last_opened_tag?==?$tag){? ??
-
????????????$this->parent?=?$this->data;? ??
-
????????????$this->last_opened_tag?=?NULL;? ??
- ????????}? ??
-
????????array_pop($this->stack);? ??
-
????????if($this->stack)?$this->parent?=?&$this->stack[count($this->stack)-1];? ??
- ????}? ??
- }? ??
-
function?count_numeric_items(&$array){? ??
-
????return?is_array($array)???count(array_filter(array_keys($array),?'is_numeric'))?:?0;? ??
- }? ??
- ?>? ??
?
http://blog.s135.com/post/253/?转载