php解析xml,并将xml转换为层级数组

1)xml_parser_create([ string $encoding ] ):建立一个新的xml解析器并返回可被其他xml函数使用的资源句柄,

参数$encoding:

php4,中用来只指定要被解析的xml输入的字符编码方式;

php5,自动侦测输入xml的编码,encoding仅用来指定解析后输出数据的编码

默认:输入编码=输出编码

php5.0.2+默认编码utf-8;之前版本,ISO-8859-1

2)bool xml_parser_set_option(resource $parser,int $option,mixed $value):为指定的的xml解析进行选项设置

parser:指向要设置选项信息的xml解析器指针

option:要设置选项的名称

value:要设置选项的值

设置成功返回true,失败返回false

选项 数据类型 描述

XML_OPTION_CASE_FOLDING int 控制在该xml解析器中大小写是否有效。默认有效,0原样输出,1转换为大写,只控制输出样式

XML_OPTION_SKIP_TAGSTART int 指明在一个标记名前应略过几个字符

XML_OPTION_SKIP_WHITE int 是否略过由空白字符组成的值

XML_OPTION_TARGET_ENCODING string

3)int xml_parse_into_struct(resource $parser,string $data,array &$values [,array &$index]):将xml

文件解析到两个对应的数组中,index参数含有指向values数组中对应值的指针,该函数返回的是一级数组,不想dom树那样有层级关系

失败返回0,成功返回1

4)eg:

源文件:

<?xml version="1.0" encoding="utf-8"?>

<newdata>

<version a="xxx">aaaa</version>

<sample><![CDATA[0]]></sample>

<all><![CDATA[https]]></all>

</newdata>

value结果:

Array

(

[0] => Array

(

//标签名

[tag] => newdata

//节点状态,open:含有子标签,起始标签;close:open的闭合部分;complete:无子标签

[type] => open

//层级

[level] => 1

)

[1] => Array

(

[tag] => version

[type] => complete

[level] => 2

//节点属性数组

[attributes] => Array

(

[a] => xxx

)

//节点值

[value] => aaaa

)

[2] => Array

(

[tag] => sample

[type] => complete

[level] => 2

[value] => 0

)

[3] => Array

(

[tag] => all

[type] => complete

[level] => 2

[value] => https

)

[4] => Array

(

[tag] => newdata

[type] => close

[level] => 1

)

)

索引结果:

Array

(

//节点名称

[newdata] => Array

(

[0] => 0//节点起始索引

[1] => 4//节点结束索引

)

[version] => Array

(

[0] => 1

)

[sample] => Array

(

[0] => 2

)

[all] => Array

(

[0] => 3

)

)

5)将xml转换为array的函数:

/**

* 将xml字符串转换为数组

* @param string $contents

* @param string $encoding

* @param int $get_attrbutes

* @param string $priority

* @param array

*/

public static function xml2Array($contents = NULL, $encoding = ‘UTF-8‘, $get_attributes = 1, $priority = ‘tag‘) {

if(!$contents) {

return array();

}

if(!function_exists(‘xml_parser_create‘)) {

return array();

}

//xml解析器

$parser = xml_parser_create(‘‘);

xml_parser_set_option($parser,XML_OPTION_TARGET_ENCODING,$encoding);

//将标签原样输出,不转换成大写

xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0);

//是否忽略空白字符

xml_parser_set_option($parser,XML_OPTION_SKIP_WHITE,1);

//$xml_values,$index引用类型,将文本解析到指定的数组变量中

xml_parse_into_struct($parser, trim($contents), $xml_values/*,$index*/);

//释放解析器

xml_parser_free($parser);

if(!$xml_values)

return array();

$xml_array = array();

$parents = array();

$opened_tags = array();

$arr = array();

//当前操作结构的指针

$current = & $xml_array;

//同级结构下重复标签的计数

$repeated_tag_index = array();

foreach ($xml_values as $data) {

//删除属性和值,确保每次用到的是新的

unset($attributes, $value);

//将标签结构数组,释放到当前的变量域中

extract($data);

//存当前标签的结果

$result = array();

//存属性

$attributes_data = array();

//标签有value

if(isset($value)) {

if($priority == ‘tag‘){

$result = trim($value);

}else{

$result[‘value‘] = trim($value);

}

}

//标签有属性,且不忽略

if($get_attributes && isset($attributes)) {

foreach ($attributes as $attr => $val) {

if ($priority == ‘tag‘){//放入单独记录属性的数组中

$attributes_data[$attr] = $val;

}else{//统一放入$result中

$result[‘attr‘][$attr] = $val;

}

}

}

//处理节点关系

if ($type == "open") {//有子节点标签

$parent[$level - 1] = & $current; //$parent[$level - 1],指向复合标签的起始处

if (!is_array($current) || (!in_array($tag, array_keys($current)))) {//xml复合标签的第一个

$current[$tag] = $result;//属性独立

/*处理结果

[tag] => Array

(

[value] => aaaa,

[attr] => Array

(

[a] => xxx

)

)

*/

if ($attributes_data){

$current[$tag . ‘_attr‘] = $attributes_data;

/*处理结果

[tag] => xxxx,

[tag_attr] => Array

(

[a] => xxx

)

*/

}

$repeated_tag_index[$tag . ‘_‘ . $level] = 1;//记录同级中该标签重复的个数

//指针重新指向符合标签的子标签

$current = & $current[$tag];

}else {

if (isset($current[$tag][0])) {//第3+个同级复合标签

$current[$tag][$repeated_tag_index[$tag . ‘_‘ . $level]] = $result;

$repeated_tag_index[$tag . ‘_‘ . $level] ++;

} else {//第2个同级复合标签

//在关联数组外包一层索引数组

$current[$tag] = array(

$current[$tag],

$result

);

$repeated_tag_index[$tag . ‘_‘ . $level] = 2;

//此处只记录第一个重复标签的属性,可能有bug,需注意!

//要想区别各子标签的属性,需要将$priority设成非‘tag‘

if (isset($current[$tag . ‘_attr‘])) {

$current[$tag][‘0_attr‘] = $current[$tag . ‘_attr‘];

unset($current[$tag . ‘_attr‘]);

}

}

//记录最后一个重复子标签的索引

$last_item_index = $repeated_tag_index[$tag . ‘_‘ . $level] - 1;

//指针指向下一个子标签

$current = & $current[$tag][$last_item_index];

}

} elseif ($type == "complete") {

//第一个complete类型的标签

if (!isset($current[$tag])) {

$current[$tag] = $result;

$repeated_tag_index[$tag . ‘_‘ . $level] = 1;

if ($priority == ‘tag‘ && $attributes_data)

$current[$tag . ‘_attr‘] = $attributes_data;

}

else {

//第3+个同级子标签

//此处只有$current[$tag][0],不行,因为可能索引到字符串的第一个字符

if(isset($current[$tag][0]) && !is_array($current[$tag])){

print_r($current);exit();

}

if(isset($current[$tag][0]) && is_array($current[$tag])) {

$current[$tag][$repeated_tag_index[$tag . ‘_‘ . $level]] = $result;

//子标签的属性不忽略

if ($get_attributes &&  $priority == ‘tag‘ && $attributes_data) {

$current[$tag][$repeated_tag_index[$tag . ‘_‘ . $level] . ‘_attr‘] = $attributes_data;

}

$repeated_tag_index[$tag . ‘_‘ . $level] ++;

}else{//第2个同级子标签

$current[$tag] = array(

$current[$tag],

$result

);

$repeated_tag_index[$tag . ‘_‘ . $level] = 1;

if ($priority == ‘tag‘ && $get_attributes) {

if (isset($current[$tag . ‘_attr‘])) {

$current[$tag][‘0_attr‘] = $current[$tag . ‘_attr‘];

unset($current[$tag . ‘_attr‘]);

}

if ($attributes_data) {

$current[$tag][$repeated_tag_index[$tag . ‘_‘ . $level] . ‘_attr‘] = $attributes_data;

}

}

$repeated_tag_index[$tag . ‘_‘ . $level] ++;

}

}

}elseif($type == ‘close‘){

//闭合标签和起始标签level相同,因此进入complete类型的子标签后,可以通过父节点的close标签,可以指回到父节点

$current = & $parent[$level - 1];

}

}

return $xml_array;

}

时间: 2024-10-21 22:31:14

php解析xml,并将xml转换为层级数组的相关文章

js解析xml字符串或xml文件,将其转换为xml对象

注:判断是否是ie浏览器和非ie浏览器的方法有多种,在此只介绍用例中的方法: 1.解析xml字符串,得到xml对象的方式: function createXml(str){ if(document.all){//IE浏览器     var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");        xmlDoc.async = false;     xmlDoc.loadXML(str);     return xmlDoc; } el

js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中

ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId = 'jUploadFrame' + id; if(window.ActiveXObject) { var io = document.createElement('<iframe id="' + frameId + '" name="' + frameId + '&qu

7.数据本地化CCString,CCArray,CCDictionary,tinyxml2,写入UserDefault.xml文件,操作xml,解析xml

 数据本地化 A CCUserDefault 系统会在默认路径cocos2d-x-2.2.3\projects\Hello\proj.win32\Debug.win32下生成一个名为UserDefault.xml.所有的key皆为char *型,value类型为bool intfloat double std::string. 读操作 bool getBoolForKey(const char* pKey); bool getBoolForKey(const char* pKey, bool

JAVASE02-Unit012: Unit07: XML语法 、 XML解析

Unit07: XML语法 . XML解析 emplist.xml <?xml version="1.0" encoding="UTF-8"?> <list> <emp id="1"> <name>张三</name> <age>34</age> <gender>男</gender> <salary>3000</salary

JS解析XML文件和XML字符串

JS解析XML文件 <script type='text/javascript'>    loadXML = function(xmlFile){        var xmlDoc=null;        //判断浏览器的类型        //支持IE浏览器        if(!window.DOMParser && window.ActiveXObject){            var xmlDomVersions = ['MSXML.2.DOMDocument.

xml规范及xml解析

http://www.cnblogs.com/wang-meng/p/5374498.html 1,XML基础介绍 xml的概念: XML 指可扩展标记语言(EXtensible Markup Language),也是一种标记语言,很类似 HTML.           它的设计宗旨是传输数据,而非显示数据它;标签没有被预定义,需要自行定义标签. xml的作用: XML 是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行.简单的说,我们在开发中使用XML主要有以

利用XPath解析带有xmlns的XML文件

在.net中,编写读取xml 的程序中提示"未将对象引用设置到对象的实例",当时一看觉得有点奇怪.为什么在读取xml数据的时候也要实例化一个对象.google了才知道,xml文件中加入了xmlns表示名称空间,但同时Xpath也必须加上. 如之前我们的xml文件定义为: <Project Name="目标计划项目"> <Process Name="个人月度计划" Description="个人月度计划" Ve

JavaScript之Ajax-4 XML解析(JavaScript中的XML、Ajax返回并解析XML)

一.JavaScript中的XML XML DOM对象 - IE 浏览器通过 ActiveXObject 对象得到 XML DOM 对象 - 其他浏览器通过 DOMParser 对象得到 XML DOM 对象 XML DOM对象的支持 - XML DOM(XML Document Object Model)定义了访问和操作XML文档的标准方法 - DOM 把 XML 文档作为树结构来查看.能够通过DOM树来访问所有元素 加载并解析XML字符串 二.Ajax返回并解析XML 使用XHR发送XML字

WebService传递XML数据 C#DataSet操作XML 解析WebService返回的XML数据

Webservice传递的数据只能是序列化的数据,典型的就是xml数据.   /// <summary>         /// 通过用户名和密码 返回下行数据         /// </summary>         /// <param name="UserName">用户名</param>         /// <param name="UserPwd">密码</param>