由于目前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;
}
}
?>
2.读取文件夹下所有配置文件并进行转化操作
<?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>";
?>