由于目前php使用simple_load_file和xpath解析xml数据相当慢,然后实现了以下程序直接把XML文件转化成PHP文件,即直接在PHP文件中定义数组包含XML数据,然后在使用的地方直接加载此PHP文件,引用里面的数组。现在给出代码,里面包含对文件夹中所有文件的读取,递归建立目录,XML读取等相关点。
1.xml解析成数组类
<?php /** * Created by zhangwu. * Date: 12-7-17 * Time: 下午2:37 */ class XmlToArray { private static $xml="test.xml"; private static $contentAsName="content"; //如果有content设置,默认用content做数组key private static $attributesAsName="attributes";//如果有attributes设置,默认用attributes做数组key private static $xmlPool = array(); public static function setXml( $xmlstr ) { self::$xml = $xmlstr; } public static function setContentAsName( $name ) { self::$contentAsName = $name; } public static function setAttributeAsName( $name ) { self::$attributesAsName = $name; } private static function createXMLArray( $node, &$parent_node, $node_index = 0 ) { $node_attrbutes= array(); $node_name = $node->getName(); $attributes = $node->attributes(); $children = $node->children (); //遍历节点上的所有属性 foreach( $attributes as $attrname => $attrvalue ) { $attrvalue = ( string )$attrvalue ; $node_attrbutes[ $attrname ] = trim( $attrvalue ); } //建立节点数组,包含contentAsName和attributesAsName两个数组键 //如果$node中的content没有设置,则为空 (eg:<test>这个地方没有任何值</test>) $content = ""; if( count($children) == 0 ) { $content = ( string ) $node; //此处会默认给出$node所代表结点的content值 } $node_array = array( self::$attributesAsName => $node_attrbutes , self::$contentAsName => trim( $content ) ); //设置层级关系 if( !isset( $parent_node[ $node_name ] ) ) { $is = count( $parent_node ); if( !isset( $parent_node[ self::$attributesAsName ] ) && count( $parent_node ) > 0 ) { $last_index = count( $parent_node ) -1; $parent_node =& $parent_node[ $last_index ]; $parent_node[ $node_name ] = $node_array; } else { $parent_node[ $node_name ] = $node_array; } } else { $append = &$parent_node[ $node_name ]; if( isset( $append[ self::$attributesAsName ] ) ) { $parent_node[ $node_name ] = array( $append ); $append = &$parent_node[ $node_name ]; } if( isset( $append[ $node_index ] ) ) { $append = &$append[ $node_index ]; } // 追加 array_push( $append , $node_array ); } $index = 0 ; // 递归操作 foreach( $children as $childnode ) { $parent = &$parent_node[ $node_name ]; self::createXMLArray( $childnode, $parent, $index++ ); } return $parent_node ; } public static function parseXml( $isfromstring=false, $isjson=false ) { if( $isfromstring ) { $root = @simplexml_load_string ( self::$xml ) ; } else { $root = @simplexml_load_file ( self::$xml) ; } if ( $root !== false) { $parent_node = array(); $array = self::createXMLArray( $root ,$parent_node ); return $isjson ? json_encode( $array ) : $array ; } return false; } public static function getXMLByName( $name, $ext = null ) { if( !isset(self::$xmlPool[$name]) ) { if( $ext == null ) { $ext = 'xml'; self::setXml("$name.$ext"); } else { self::setXml($name); } $ret = self::parseXml(); if ( $ret !== false ) { self::$xmlPool[$name] = $ret; } } if( isset(self::$xmlPool[$name]) ) return self::$xmlPool[$name]; else return false; } } ?>
<?php /** * Created by zhangwu. * Date: 12-7-19 * Time: 下午3:30 */ require_once("xml.php"); /* * 递归获取指定路径下的所有文件或匹配指定正则的文件(不包括“.”和“..”),结果以数组形式返回 * @param string $dir * @param string $pattern * @return array */ function file_list( $dir, $pattern="" ) { $arr = array(); $dir_handle = opendir($dir); if( $dir_handle ) { // 这里必须严格比较,因为返回的文件名可能是“0” while( ($file = readdir($dir_handle)) !== false ) { if( $file === '.' || $file === '..' ) { continue; } $tmp = realpath($dir.'/'.$file); if( is_dir($tmp) ) { $retArr = file_list($tmp,$pattern); if( !empty($retArr) ) { $arr[] = $retArr; } } else { if( $pattern === "" || preg_match($pattern,$tmp) ) { $arr[] = $tmp; } } } closedir($dir_handle); } return $arr; } //递归建立多级目录 function Directory( $dir ) { return is_dir($dir) or (Directory(dirname($dir)) and mkdir($dir, 0777)); } // 把指定目录下所有以".XML"扩展名的文件(不区分大小写) // 转化成php数组的形式的PHP文件到指定目录 function xml_to_php( $xmlpath, $phppath, &$files ) { foreach( $files as $index => $child ) { if( is_array($child) ) { //递归操作 xml_to_php($xmlpath, $phppath, &$child); } else { $array1 = Array($xmlpath, ".xml"); $array2 = Array($phppath, ".php"); $newpath = str_replace($array1, $array2, $child); Directory(dirname($newpath)); $result = var_export (XmlToArray::getXMLByName($child, true), true); $fp = fopen($newpath, "w"); $name = basename($newpath, ".php"); fwrite($fp, "<?php\r\n$"); fwrite($fp, "$name = "); fwrite($fp, $result); fwrite($fp, "\r\n?>"); fclose($fp); } } } function do_change( $xmlpath, $phppath ) { //首先建立主目录 Directory($phppath); $files = file_list($xmlpath, '/\.xml$/i'); xml_to_php($xmlpath, $phppath, &$files); } //此处可以更改到相应的文件目录 do_change((dirname(__FILE__) . "\config"), (dirname(__FILE__) . "\config2")); echo "<h2 style=\"color:red\">change success</h2>"; ?>