您的位置:首页 > 编程语言 > PHP开发

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

2017-04-03 20:31 411 查看
<?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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: