| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 | <?php/** * Created by PhpStorm. * User: tandunzhao * Date: 2017/12/13 * Time: 下午2:54 */namespace App\Libs\allinpay;use XMLReader;use DOMDocument;use Exception;class ArrayXML{    protected $bOptimize = FALSE;    public $bFormatted = FALSE;    public function parseString( $sXml , $bOptimize = FALSE) {        $oXml = new XMLReader();        $this -> bOptimize = (bool) $bOptimize;        try {            // Set String Containing XML data            $oXml->XML($sXml);            // Parse Xml and return result            return $this->parseXml($oXml);        } catch (Exception $e) {            echo $e->getMessage();        }    }    public function parseFile( $sXmlFilePath , $bOptimize = false ) {        $oXml = new XMLReader();        $this -> bOptimize = (bool) $bOptimize;        try {            // Open XML file            $oXml->open($sXmlFilePath);            // Parse Xml and return result            return $this->parseXml($oXml);        } catch (Exception $e) {            echo $e->getMessage(). ' | Try open file: '.$sXmlFilePath;        }    }    protected function parseXml( XMLReader $oXml ) {        $aAssocXML = null;        $iDc = -1;        while($oXml->read()){            switch ($oXml->nodeType) {                case XMLReader::END_ELEMENT:                    if ($this->bOptimize) {                        $this->optXml($aAssocXML);                    }                    return $aAssocXML;                case XMLReader::ELEMENT:                    if(!isset($aAssocXML[$oXml->name])) {                        if($oXml->hasAttributes) {                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);                        } else {                            if($oXml->isEmptyElement) {                                $aAssocXML[$oXml->name] = '';                            } else {                                $aAssocXML[$oXml->name] = $this->parseXML($oXml);                            }                        }                    } elseif (is_array($aAssocXML[$oXml->name])) {                        if (!isset($aAssocXML[$oXml->name][0]))                        {                            $temp = $aAssocXML[$oXml->name];                            foreach ($temp as $sKey=>$sValue)                                unset($aAssocXML[$oXml->name][$sKey]);                            $aAssocXML[$oXml->name][] = $temp;                        }                        if($oXml->hasAttributes) {                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);                        } else {                            if($oXml->isEmptyElement) {                                $aAssocXML[$oXml->name][] = '';                            } else {                                $aAssocXML[$oXml->name][] = $this->parseXML($oXml);                            }                        }                    } else {                        $mOldVar = $aAssocXML[$oXml->name];                        $aAssocXML[$oXml->name] = array($mOldVar);                        if($oXml->hasAttributes) {                            $aAssocXML[$oXml->name][] = $oXml->isEmptyElement ? '' : $this->parseXML($oXml);                        } else {                            if($oXml->isEmptyElement) {                                $aAssocXML[$oXml->name][] = '';                            } else {                                $aAssocXML[$oXml->name][] = $this->parseXML($oXml);                            }                        }                    }                    if($oXml->hasAttributes) {                        $mElement =& $aAssocXML[$oXml->name][count($aAssocXML[$oXml->name]) - 1];                        while($oXml->moveToNextAttribute()) {                            $mElement[$oXml->name] = $oXml->value;                        }                    }                    break;                case XMLReader::TEXT:                case XMLReader::CDATA:                    $aAssocXML[++$iDc] = $oXml->value;            }        }        return $aAssocXML;    }    public function optXml(&$mData) {        if (is_array($mData)) {            if (isset($mData[0]) && count($mData) == 1 ) {                $mData = $mData[0];                if (is_array($mData)) {                    foreach ($mData as &$aSub) {                        $this->optXml($aSub);                    }                }            } else {                foreach ($mData as &$aSub) {                    $this->optXml($aSub);                }            }        }    }    public function fixCDATA($string) {        //fix CDATA tags        $find[]     = '<![CDATA[';        $replace[] = '<![CDATA[';        $find[]     = ']]>';        $replace[] = ']]>';        $string = str_ireplace($find, $replace, $string);        return $string;    }    public function is_assoc( $array ) {        return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));    }    public function toXml($data, $rootNodeName = 'data', &$xml=null)    {        // turn off compatibility mode as simple xml throws a wobbly if you don't.        if ( ini_get('zend.ze1_compatibility_mode') == 1 ) ini_set ( 'zend.ze1_compatibility_mode', 0 );        if ( is_null( $xml ) ) {            $xml = simplexml_load_string(stripslashes("<?xml version='1.0' encoding='UTF-8'?><$rootNodeName></$rootNodeName>"));        }        // loop through the data passed in.        foreach( $data as $key => $value ) {            // no numeric keys in our xml please!            $numeric = false;            if ( is_numeric( $key ) ) {                $numeric = 1;                $key = $rootNodeName;            }            // delete any char not allowed in XML element names            $key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);            //check to see if there should be an attribute added (expecting to see _id_)            $attrs = false;            //if there are attributes in the array (denoted by attr_**) then add as XML attributes            if ( is_array( $value ) ) {                foreach($value as $i => $v ) {                    $attr_start = false;                    $attr_start = stripos($i, 'attr_');                    if ($attr_start === 0) {                        $attrs[substr($i, 5)] = $v; unset($value[$i]);                    }                }            }            // if there is another array found recursively call this function            if ( is_array( $value ) ) {                if ( $this->is_assoc( $value ) || $numeric ) {                    // older SimpleXMLElement Libraries do not have the addChild Method                    if (method_exists('SimpleXMLElement','addChild')) {                        $node = $xml->addChild( $key, null);                        if ($attrs) {                            foreach($attrs as $key => $attribute) {                                $node->addAttribute($key, $attribute);                            }                        }                    }                }else{                    $node =$xml;                }                // recrusive call.                if ( $numeric ) $key = 'anon';                $this->toXml( $value, $key, $node );            } else {                // older SimplXMLElement Libraries do not have the addChild Method                if (method_exists('SimpleXMLElement','addChild')) {                    $childnode = $xml->addChild( $key, $value);                    if ($attrs) {                        foreach($attrs as $key => $attribute) {                            $childnode->addAttribute($key, $attribute);                        }                    }                }            }        }        if ($this->bFormatted) {            // if you want the XML to be formatted, use the below instead to return the XML            $doc = new DOMDocument('1.0');            $doc->preserveWhiteSpace = false;            @$doc->loadXML( $this->fixCDATA($xml->asXML()) );            $doc->formatOutput = true;            return $doc->saveXML();        }        // pass back as unformatted XML        return $xml->asXML();    }    public function toXmlGBK($data, $rootNodeName = 'data', &$xml=null)    {        $xml = str_replace('<?xml version="1.0" encoding="UTF-8"?>', '<?xml version="1.0" encoding="GBK"?>', $this->toXml($data, $rootNodeName, $xml));//        dd($xml);        return mb_convert_encoding($xml, 'GBK', 'UTF-8');    }}
 |