PHP Document解析XML(对比基于事件xml解析)

来源:互联网 发布:数据库方案 编辑:程序博客网 时间:2024/06/06 03:33
<?php/** * Filename: Document.php * The description of the file: * ========================================= * Copy right 2017 * * ========================================= * Author: pengzhi * Version: 1.0.0 * Encoding:UTF-8 * Date: 2017/3/30 17:33 **/class Document{    private $document = array();    private $objDom   = null;    public function __construct()    {        $this->objDom = new DOMDocument();    }    public function getError()    {        return '';    }    public function serialize($data)    {        $arrResult = $this->parse($data);        $str = '<?xml version="1.0" encoding="utf-8"?>'."\n<root>\n";        //内容输出 深度优先搜索        $str .= $this->dfs2($arrResult, 1);        //echo '\n</root>';        $str .= "</root>";        //$str = ob_get_contents();        //ob_end_clean();        return $str;    }    /**     * 解析xml 字符串为数组形式 返回     * @param $data     * @return     */    public function parse($data)    {        Bd_Log::debug("start parse ...");        if (!$this->objDom->loadXML($data)) {            throw new RuntimeException("loadXML fail!");        }        $root = $this->objDom->documentElement;//文档根元素documentElement        $this->document = array();        if ($root) {            $this->document[$root->localName] = $this->dfs($root);        }        return $this->document;    }    /**     * 生成节点树     * @param $node     * @return array     */    public function dfs($node)    {        //echo XML_TEXT_NODE.PHP_EOL; 3        //echo $node->nodeName.PHP_EOL;        if (XML_TEXT_NODE == $node->nodeType) {            //XML_TEXT_NODE 3            return $node->nodeValue;        } else {            //XML_ELEMENT_NODE 1            $arr = array();            foreach ($node->childNodes as $idx => $subNode) {                if (XML_TEXT_NODE == $subNode->nodeType &&                    '#text' == $subNode->nodeName) {                    return $subNode->nodeValue;                }                if (1 < $node->getElementsByTagName($subNode->nodeName)->length) {                    //数组元素                    $arr[$subNode->nodeName][] = $this->dfs($subNode);                    //属性处理                    if ($subNode->attributes->length > 0) {                        $attrs = array();                        foreach ($subNode->attributes as $attrName => $attrNode) {                            $attrs[$attrName] = $attrNode->nodeValue;                        }                        $l = count($arr[$subNode->nodeName]);                        $arr[$subNode->nodeName." attr"][$l-1] = $attrs;                    }                } else {                    //普通元素                    $arr[$subNode->nodeName] = $this->dfs($subNode);                    if ($subNode->attributes->length > 0) {                        $attrs = array();                        foreach ($subNode->attributes as $attrName => $attrNode) {                            $attrs[$attrName] = $attrNode->nodeValue;                        }                        $arr[$subNode->nodeName." attr"]= $attrs;                    }                }            }            return $arr;        }    }    /**     * @param array $arr     * @return bool     */    private function isAssoc(array $arr)    {        $keys = array_keys($arr);        return $keys !== array_keys($keys);    }    /**     * @param $item     * @param int $level     * @return string     */    private function dfs2($item, $level = 1)    {        Bd_Log::trace(json_encode($item)."|level:{$level}|dfs");        $str = '';        if (!is_array($item)) {            $str .= str_repeat('\t', $level).$item."\n";        } else {            foreach ($item as $key => $val) {                if (strpos($key, 'attr') > 0) {                    continue;//属性元素 跳过                }                if (is_array($val) && !$this->isAssoc($val)) {                    //数组元素                    foreach ($val as $idx => $subval) {                        $str .= str_repeat('\t', $level)."<{$key}";                        //元素属性 todo                        if (isset($item["{$key} attr"][$idx])) {                            foreach ($item["{$key} attr"][$idx] as $k => $v) {                                $str .= " {$k}='{$v}'";                            }                        }                        $str .=">\n";                        //元素内容                        $str .= $this->dfs2($subval, $level+1);                        $str .= str_repeat('\t', $level)."</{$key}>\n";                    }                } elseif(is_array($val)){                    $str .= str_repeat('\t', $level)."<{$key}";                    //元素属性 todo                    if (isset($item["{$key} attr"])) {                        foreach ($item["{$key} attr"] as $k => $v) {                            $str .= " {$k}='{$v}'";                        }                    }                    $str .= ">\n";                    $str .= $this->dfs2($val, $level+1);                    $str .= str_repeat('\t', $level)."</{$key}>\n";                } else {                    $str .= $this->dfs2($val, $level+1);                }//if elseif else            }//foreach        }//else        return $str;    }}

0 0
原创粉丝点击