http://www.phppan.com/2009/10/phps-five-methods-of-xml-parseing/
【前言】 不管是桌面软件开发,还是WEB应用,XML无处不在! 然而在平时的工作中,仅仅是使用一些已经封装好的类对XML对于处理,包括生成,解析等。假期有空,于是将PHP中的几种XML解析方法总结如下:
以解析Google API 接口提供的天气情况为例,我们取今天的天气及气温。 API地址:http://www.google.com/ig/api?weather=shenzhen
【XML文件内容】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version ="1.0" ?>
<xml_api_reply version ="1" >
<weather module_id ="0" tab_id ="0" mobile_row ="0" mobile_zipped ="1" row ="0" section ="0" >
<forecast_information>
<city data ="Shenzhen, Guangdong" />
<postal_code data ="shenzhen" />
<latitude_e6 data ="" />
<longitude_e6 data ="" />
<forecast_date data ="2009-10-05" />
<current_date_time data ="2009-10-04 05:02:00 +0000" />
<unit_system data ="US" />
</forecast_information>
<current_conditions>
<condition data ="Sunny" />
<temp_f data ="88" />
<temp_c data ="31" />
<humidity data ="Humidity: 49%" />
<icon data ="/ig/images/weather/sunny.gif" />
<wind_condition data ="Wind: mph" />
</current_conditions>
</weather>
</xml_api_reply>
【使用DomDocument解析】
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?PHP
header ( "Content-type:text/html; Charset=utf-8" ) ;
$url = "http://www.google.com/ig/api?weather=shenzhen" ;
// 加载XML内容
$content = file_get_contents ( $url ) ;
$content = get_utf8_string( $content ) ;
$dom = DOMDocument:: loadXML ( $content ) ;
/*
此处也可使用如下所示的代码,
$dom = new DOMDocument();
$dom->load($url);
*/
$elements = $dom -> getElementsByTagName ( "current_conditions" ) ;
$element = $elements -> item ( 0 ) ;
$condition = get_google_xml_data( $element , "condition" ) ;
$temp_c = get_google_xml_data( $element , "temp_c" ) ;
echo '天气:' , $condition , '<br />' ;
echo '温度:' , $temp_c , '<br />' ;
function get_utf8_string( $content ) { // 将一些字符转化成utf8格式
$encoding = mb_detect_encoding ( $content , array ( 'ASCII' , 'UTF-8' , 'GB2312' , 'GBK' , 'BIG5' ) ) ;
return mb_convert_encoding ( $content , 'utf-8' , $encoding ) ;
}
function get_google_xml_data( $element , $tagname ) {
$tags = $element -> getElementsByTagName ( $tagname ) ; // 取得所有的$tagname
$tag = $tags -> item ( 0 ) ; // 获取第一个以$tagname命名的标签
if ( $tag -> hasAttributes ( ) ) { // 获取data属性
$attribute = $tag -> getAttribute ( "data" ) ;
return $attribute ;
} else {
return false ;
}
}
?>
这只是一个简单的示例,仅包括了loadXML, item, getAttribute,getElementsByTagName等方法,还有一些有用的方法,这个依据你的实际需要。
【XMLReader】 当我们要用php解读xml的内容时,有很多物件提供函式,让我们不用一个一个字元去解析,而只要根据标签和属性名称,就能取出文件中的属性与内容了,相较之下方便许多。其中XMLReader循序地浏览过xml档案的节点,可以想像成游标走过整份文件的节点,并抓取需要的内容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?PHP
header ( "Content-type:text/html; Charset=utf-8" ) ;
$url = "http://www.google.com/ig/api?weather=shenzhen" ;
// 加载XML内容
$xml = new XMLReader( ) ;
$xml -> open ( $url ) ;
$condition = '' ;
$temp_c = '' ;
while ( $xml -> read ( ) ) {
// echo $xml->name, "==>", $xml->depth, "<br>";
if ( ! empty ( $condition ) && ! empty ( $temp_c ) ) {
break ;
}
if ( $xml -> name == 'condition' && empty ( $condition ) ) { // 取第一个condition
$condition = $xml -> getAttribute ( 'data' ) ;
}
if ( $xml -> name == 'temp_c' && empty ( $temp_c ) ) { // 取第一个temp_c
$temp_c = $xml -> getAttribute ( 'data' ) ;
}
$xml -> read ( ) ;
}
$xml -> close ( ) ;
echo '天气:' , $condition , '<br />' ;
echo '温度:' , $temp_c , '<br />' ;
我们只是需要取第一个condition和第一个temp_c,于是遍历所有的节点,将遇到的第一个condition和第一个temp_c写入变量,最后输出。
【DOMXPath】 这种方法需要使用DOMDocument对象创建整个文档的结构,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?PHP
header ( "Content-type:text/html; Charset=utf-8" ) ;
$url = "http://www.google.com/ig/api?weather=shenzhen" ;
// 加载XML内容
$dom = new DOMDocument( ) ;
$dom -> load ( $url ) ;
$xpath = new DOMXPath( $dom ) ;
$element = $xpath -> query ( "/xml_api_reply/weather/current_conditions" ) -> item ( 0 ) ;
$condition = get_google_xml_data( $element , "condition" ) ;
$temp_c = get_google_xml_data( $element , "temp_c" ) ;
echo '天气:' , $condition , '<br />' ;
echo '温度:' , $temp_c , '<br />' ;
function get_google_xml_data( $element , $tagname ) {
$tags = $element -> getElementsByTagName ( $tagname ) ; // 取得所有的$tagname
$tag = $tags -> item ( 0 ) ; // 获取第一个以$tagname命名的标签
if ( $tag -> hasAttributes ( ) ) { // 获取data属性
$attribute = $tag -> getAttribute ( "data" ) ;
return $attribute ;
} else {
return false ;
}
}
?>
【xml_parse_into_struct】 说明:int xml_parse_into_struct ( resource parser, string data, array &values [, array &index] )
该函数将 XML 文件解析到两个对应的数组中,index 参数含有指向 values 数组中对应值的指针。最后两个数组参数可由指针传递给函数。 注意: xml_parse_into_struct() 失败返回 0,成功返回 1。这和 FALSE 与 TRUE 不同,使用例如 === 的运算符时要注意。
1
2
3
4
5
6
7
8
9
10
11
12
<?PHP
header ( "Content-type:text/html; Charset=utf-8" ) ;
$url = "http://www.google.com/ig/api?weather=shenzhen" ;
// 加载XML内容
$content = file_get_contents ( $url ) ;
$p = xml_parser_create ( ) ;
xml_parse_into_struct ( $p , $content , $vals , $index ) ;
xml_parser_free ( $p ) ;
echo '天气:' , $vals [ $index [ 'CONDITION' ] [ 0 ] ] [ 'attributes' ] [ 'DATA' ] , '<br />' ;
echo '温度:' , $vals [ $index [ 'TEMP_C' ] [ 0 ] ] [ 'attributes' ] [ 'DATA' ] , '<br />' ;
【Simplexml】 此方法在PHP5中可用 这个在google的官方文档中有相关的例子,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Charset: utf-8
/**
* 用php Simplexml 调用google天气预报api,和g官方的例子不一样
* google 官方php domxml 获取google天气预报的例子
* http://www.google.com/tools/toolbar/buttons/intl/zh-CN/apis/howto_guide.html
*
* @copyright Copyright (c) 2008 <cmpan(at)qq.com>
* @license New BSD License
* @version 2008-11-9
*/
// 城市,用城市拼音
$city = empty ( $_GET [ 'city' ] ) ? 'shenzhen' : $_GET [ 'city' ] ;
$content = file_get_contents ( "http://www.google.com/ig/api?weather=$city &hl=zh-cn" ) ;
$content || die ( "No such city's data" ) ;
$content = mb_convert_encoding ( $content , 'UTF-8' , 'GBK' ) ;
$xml = simplexml_load_string ( $content ) ;
$date = $xml -> weather -> forecast_information -> forecast_date -> attributes ( ) ;
$html = $date . "<br>\r \n " ;
$current = $xml -> weather -> current_conditions ;
$condition = $current -> condition -> attributes ( ) ;
$temp_c = $current -> temp_c -> attributes ( ) ;
$humidity = $current -> humidity -> attributes ( ) ;
$icon = $current -> icon -> attributes ( ) ;
$wind = $current -> wind_condition -> attributes ( ) ;
$condition && $condition = $xml -> weather -> forecast_conditions -> condition -> attributes ( ) ;
$icon && $icon = $xml -> weather -> forecast_conditions -> icon -> attributes ( ) ;
$html .= "当前: {$condition} , {$temp_c} °C,<img src='http://www.google.com/ig{$icon} '/> {$humidity} {$wind} <br />\r \n " ;
foreach ( $xml -> weather -> forecast_conditions as $forecast ) {
$low = $forecast -> low -> attributes ( ) ;
$high = $forecast -> high -> attributes ( ) ;
$icon = $forecast -> icon -> attributes ( ) ;
$condition = $forecast -> condition -> attributes ( ) ;
$day_of_week = $forecast -> day_of_week -> attributes ( ) ;
$html .= "{$day_of_week} : {$high} / {$low} °C, {$condition} <img src='http://www.google.com/ig{$icon} ' /><br />\r \n " ;
}
header ( 'Content-type: text/html; Charset: utf-8' ) ;
print $html ;
?>