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');
- }
- }
|