• PHP流式读取XML文件


      之前在项目中有读取XML的需求,一开始采用的是simplexml将xml文件全部load到内存里,然后一个节点一个节点读的方式,后来随着XML文件的增大,内存被撑爆了。于是赶紧想办法,于是有了流式读取。一开始老大给了我一个封装XMLReader的类,但是我发现这个类不是很符合我的要求,于是又把XMLReader按我的要求重新封装了一遍,在此感谢老大moon。

      目前我的类非常简单就提供几个方法,我提供了Demo供大家参考使用。话不多说上代码

    <?php
    /**
     *
     * @author gaoran
     * Another new parser for (X|HT)ML(stream version)
     * @version 1.0 2014-06-02 18:10:00
     * 感谢我的老大moon,之前moon写了一个XMLParser的类,但是我觉得不是我想要的,于是自己重新封装了一遍,自我感觉简单,好用
     */
    class New_XMLParser extends XMLReader{
        private $_tagName;
    
        /**
         * 设置打开xml文件的路径
         */
        public function open($xml,$encoding=null,$option=null){
            parent::open($xml, $encoding, $option);
        }
        /**
         * 设置要读取数据的节点名称
         */
        public function setTagName($tagName){
            $this->_tagName = $tagName;
        }
        /**
         * 每次读取一个节点数据,以数组格式返回
         */
        public function getData(){
            if(!$this->_tagName){return false;}
            while($this->read()){
                $tagName = $this->name;
                if($this->nodeType == XMLReader::ELEMENT && $this->_tagName == $tagName){
                    $dom = new DOMDocument('1.0', 'utf-8');
                    $d = $dom->importNode($this->expand(), true);
                    //$dom->appendChild($d);
                    $appinfo = $this->domToArray($d);
                    return $appinfo;
                }
            }
            return false;
        }
        /**
         *
         * @param SimpleXMLElement|DOMDocument|DOMNode $obj SimpleXMLElement, DOMDocument or DOMNode instance
         * @return array Array representation of the XML structure.
         */
        public static function domToArray($obj) {
            if ($obj instanceof DOMNode) {
                $obj = simplexml_import_dom($obj);
            }
    
            $result = array();
            $namespaces = array_merge(array('' => ''), $obj->getNamespaces(true));
    
            self::_toArray($obj, $result, '', array_keys($namespaces));
            return $result;
        }
        protected static function _toArray($xml, &$parentData, $ns, $namespaces) {
            $data = array();
    
            foreach ($namespaces as $namespace) {
                foreach ($xml->attributes($namespace, true) as $key => $value) {
                    if (!empty($namespace)) {
                        $key = $namespace . ':' . $key;
                    }
                    $data['@' . $key] = (string)$value;
                }
    
                foreach ($xml->children($namespace, true) as $child) {
                    self::_toArray($child, $data, $namespace, $namespaces);
                }
            }
    
            $asString = trim((string)$xml);
            if (empty($data)) {
                $data = $asString;
            } elseif (!empty($asString)) {
                $data['@'] = $asString;
            }
    
            if (!empty($ns)) {
                $ns .= ':';
            }
            $name = $ns . $xml->getName();
            if (isset($parentData[$name])) {
                if (!is_array($parentData[$name]) || !isset($parentData[$name][0])) {
                    $parentData[$name] = array($parentData[$name]);
                }
                $parentData[$name][] = $data;
            } else {
                $parentData[$name] = $data;
            }
        }
        /*
         * 关闭XML流
         */
        public function close(){
            parent::close();
        }
    }
    class Demo{
        public function run(){
            $im = new New_XMLParser();
            $im->open('xmlfile');
    
            $im->setTagName("webName");
            print_r($im->getData());
    
            $im->setTagName("webSiteUrl");
            print_r($im->getData());
    
            $im->setTagName("app");
            print_r($im->getData());
    
            //$im->open('xmlfile');
    
            $i = 0;
            while($i < 3 && $appinfo = $im->getData()){
                print_r($appinfo);
                $i ++;
            }
            $im->close();
        }
    }
    $d = new Demo();
    $d->run();
    

      

    目前够用了,以后继续改进吧,欢迎大家拍砖,一起进步完善。

  • 相关阅读:
    程序员与HR博弈之:有城府的表达你的兴趣爱好
    也谈创业企业CEO该拿多少工资
    今日互联网关注(写在清明节后):每天都有值得关注的大变化
    另眼看纸媒电商的发展
    今日互联网关注(20140331):善待和你裸婚的员工
    看着烧了十几亿的打车软件,我们能跟着模仿点什么?
    一款云端开发环境平台,思考互联网产品模式
    2018年的医保控费思路
    新形势下国家医疗保障局信息化建设注意点(五)强化监管信息化
    新形势下国家医疗保障局信息化建设注意点(四)推进电子医保卡
  • 原文地址:https://www.cnblogs.com/xiongji/p/3764578.html
Copyright © 2020-2023  润新知