PHP解析XML的几种方法(附代码)

不管是桌面软件开发,还是WEB应用,XML无处不在!

然而在平时的工作中,仅仅是使用一些已经封装好的类对XML对于处理,包括生成,解析等。假期有空,于是将PHP中的几种XML解析方法总结如下:

以解析Google API 接口提供的天气情况为例,我们取今天的天气及气温。

API地址:http://www.google.com/ig/api?weather=shenzhen

【XML文件内容】

  1. <?xml version="1.0"?>
  2. <xml_api_reply version="1">
  3. <weather module_ tab_ mobile_row="0" mobile_zipped="1" row="0" section="0" >
  4. <forecast_information>
  5. <city data="Shenzhen, Guangdong"/>
  6. <postal_code data="shenzhen"/>
  7. <latitude_e6 data=""/>
  8. <longitude_e6 data=""/>
  9. <forecast_date data="2009-10-05"/>
  10. <current_date_time data="2009-10-04 05:02:00 +0000"/>
  11. <unit_system data="US"/>
  12. </forecast_information>
  13. <current_conditions>
  14. <condition data="Sunny"/>
  15. <temp_f data="88"/>
  16. <temp_c data="31"/>
  17. <humidity data="Humidity: 49%"/>
  18. <icon data="/ig/images/weather/sunny.gif"/>
  19. <wind_condition data="Wind: mph"/>
  20. </current_conditions>
  21. </weather>
  22. </xml_api_reply>

【使用DomDocument解析】

  1. <?PHP
  2. header("Content-type:text/html; Charset=utf-8");
  3. $url = "http://www.google.com/ig/api?weather=shenzhen";
  4. // 加载XML内容
  5. $content = file_get_contents($url);
  6. $content = get_utf8_string($content);
  7. $dom = DOMDocument::loadXML($content);
  8. /*
  9. 此处也可使用如下所示的代码,
  10. $dom = new DOMDocument();
  11. $dom->load($url);
  12. */
  13. $elements = $dom->getElementsByTagName("current_conditions");
  14. $element = $elements->item(0);
  15. $condition = get_google_xml_data($element, "condition");
  16. $temp_c = get_google_xml_data($element, "temp_c");
  17. echo '天气:', $condition, '<br />';
  18. echo '温度:', $temp_c, '<br />';
  19. function get_utf8_string($content) { // 将一些字符转化成utf8格式
  20. $encoding = mb_detect_encoding($content, array('ASCII','UTF-8','GB2312','GBK','BIG5'));
  21. return mb_convert_encoding($content, 'utf-8', $encoding);
  22. }
  23. function get_google_xml_data($element, $tagname) {
  24. $tags = $element->getElementsByTagName($tagname); // 取得所有的$tagname
  25. $tag = $tags->item(0); // 获取第一个以$tagname命名的标签
  26. if ($tag->hasAttributes()) { // 获取data属性
  27. $attribute = $tag->getAttribute("data");
  28. return $attribute;
  29. }else {
  30. return false;
  31. }
  32. }
  33. ?>

这只是一个简单的示例,仅包括了loadXML, item, getAttribute,getElementsByTagName等方法,还有一些有用的方法,这个依据你的实际需要。

【XMLReader】

当我们要用php解读xml的内容时,有很多物件提供函式,让我们不用一个一个字元去解析,而只要根据标签和属性名称,就能取出文件中的属性与内容了,相较之下方便许多。其中XMLReader循序地浏览过xml档案的节点,可以想像成游标走过整份文件的节点,并抓取需要的内容。

  1. <?PHP
  2. header("Content-type:text/html; Charset=utf-8");
  3. $url = "http://www.google.com/ig/api?weather=shenzhen";
  4. // 加载XML内容
  5. $xml = new XMLReader();
  6. $xml->open($url);
  7. $condition = '';
  8. $temp_c = '';
  9. while ($xml->read()) {
  10. // echo $xml->name, "==>", $xml->depth, "<br>";
  11. if (!emptyempty($condition) && !emptyempty($temp_c)) {
  12. break;
  13. }
  14. if ($xml->name == 'condition' && emptyempty($condition)) { // 取第一个condition
  15. $condition = $xml->getAttribute('data');
  16. }
  17. if ($xml->name == 'temp_c' && emptyempty($temp_c)) { // 取第一个temp_c
  18. $temp_c = $xml->getAttribute('data');
  19. }
  20. $xml->read();
  21. }
  22. $xml->close();
  23. echo '天气:', $condition, '<br />';
  24. echo '温度:', $temp_c, '<br />';
我们只是需要取第一个condition和第一个temp_c,于是遍历所有的节点,将遇到的第一个condition和第一个temp_c写入变量,最后输出。

【DOMXPath】

这种方法需要使用DOMDocument对象创建整个文档的结构,

  1. <?PHP
  2. header("Content-type:text/html; Charset=utf-8");
  3. $url = "http://www.google.com/ig/api?weather=shenzhen";
  4. // 加载XML内容
  5. $dom = new DOMDocument();
  6. $dom->load($url);
  7. $xpath = new DOMXPath($dom);
  8. $element = $xpath->query("/xml_api_reply/weather/current_conditions")->item(0);
  9. $condition = get_google_xml_data($element, "condition");
  10. $temp_c = get_google_xml_data($element, "temp_c");
  11. echo '天气:', $condition, '<br />';
  12. echo '温度:', $temp_c, '<br />';
  13. function get_google_xml_data($element, $tagname) {
  14. $tags = $element->getElementsByTagName($tagname); // 取得所有的$tagname
  15. $tag = $tags->item(0); // 获取第一个以$tagname命名的标签
  16. if ($tag->hasAttributes()) { // 获取data属性
  17. $attribute = $tag->getAttribute("data");
  18. return $attribute;
  19. }else {
  20. return false;
  21. }
  22. }
  23. ?>

【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. <?PHP
  2. header("Content-type:text/html; Charset=utf-8");
  3. $url = "http://www.google.com/ig/api?weather=shenzhen";
  4. // 加载XML内容
  5. $content = file_get_contents($url);
  6. $p = xml_parser_create();
  7. xml_parse_into_struct($p, $content, $vals, $index);
  8. xml_parser_free($p);
  9. echo '天气:', $vals[$index['CONDITION'][0]]['attributes']['DATA'], '<br />';
  10. echo '温度:', $vals[$index['TEMP_C'][0]]['attributes']['DATA'], '<br />';

【Simplexml】

此方法在PHP5中可用

这个在google的官方文档中有相关的例子,如下:

  1. // Charset: utf-8
  2. /**
  3. * 用php Simplexml 调用google天气预报api,和g官方的例子不一样
  4. * google 官方php domxml 获取google天气预报的例子
  5. * http://www.google.com/tools/toolbar/buttons/intl/zh-CN/apis/howto_guide.html
  6. *
  7. * @copyright Copyright (c) 2008 <cmpan(at)qq.com>
  8. * @license New BSD License
  9. * @version 2008-11-9
  10. */
  11. // 城市,用城市拼音
  12. $city = emptyempty($_GET['city']) ? 'shenzhen' : $_GET['city'];
  13. $content = file_get_contents("http://www.google.com/ig/api?weather=$city&hl=zh-cn");
  14. $content || die("No such city's data");
  15. $content = mb_convert_encoding($content, 'UTF-8', 'GBK');
  16. $xml = simplexml_load_string($content);
  17. $date = $xml->weather->forecast_information->forecast_date->attributes();
  18. $html = $date. "<br>\r\n";
  19. $current = $xml->weather->current_conditions;
  20. $condition = $current->condition->attributes();
  21. $temp_c = $current->temp_c->attributes();
  22. $humidity = $current->humidity->attributes();
  23. $icon = $current->icon->attributes();
  24. $wind = $current->wind_condition->attributes();
  25. $condition && $condition = $xml->weather->forecast_conditions->condition->attributes();
  26. $icon && $icon = $xml->weather->forecast_conditions->icon->attributes();
  27. $html.= "当前: {$condition}, {$temp_c}°C,<img src='http://www.google.com/ig{$icon}'/> {$humidity} {$wind} <br />\r\n";
  28. foreach($xml->weather->forecast_conditions as $forecast) {
  29. $low = $forecast->low->attributes();
  30. $high = $forecast->high->attributes();
  31. $icon = $forecast->icon->attributes();
  32. $condition = $forecast->condition->attributes();
  33. $day_of_week = $forecast->day_of_week->attributes();
  34. $html.= "{$day_of_week} : {$high} / {$low} °C, {$condition} <img src='http://www.google.com/ig{$icon}' /><br />\r\n";
  35. }
  36. header('Content-type: text/html; Charset: utf-8');
  37. print $html;
  38. ?>