php xml 空格,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_FOLDINGint 控制在该xml解析器中大小写是否有效。默认有效,0原样输出,1转换为大写,只控制输出样式

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

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

XML_OPTION_TARGET_ENCODINGstring

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

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

失败返回0,成功返回1

4)eg:

源文件:

aaaa

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;

}

6)关于xml中的CDATA:

在XML文档中的所有文本都会被解析器解析。只有在CDATA部件之内的文本会被解析器忽略

一个 CDATA 部件以"< ![CDATA[" 标记开始,以"]]>"标记结束:

< script>    < ![CDATA[    function matchwo(a,b)    {        if (a < b && a < 0) then        {            return 1        }        else        {            return 0        }      }     ]]>    < /script>

在前面的例子中,所有在CDATA部件之间的文本都会被解析器忽略。

CDATA注意事项:    CDATA部件之间不能再包含CDATA部件(不能嵌套)。如果CDATA部件包含了字符"]]>" 或者"< !        [CDATA[" ,将很有可能出错哦。

同样要注意在字符串"]]>"之间没有空格或者换行符

参考地址:http://www.cnblogs.com/chenqingwei/archive/2010/04/21/1717237.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值