>php教程 >PHP源码 >PHP读取XML

PHP读取XML

PHP中文网
PHP中文网원래의
2016-05-25 17:07:211260검색

php读取xml

1.php代码

books.xml文件:
 
<books>
<book>
<author>Jack Herrington</author>
<title>PHP Hacks</title>
<publisher>O&#39;Reilly</publisher>
</book>
<book>
<author>Jack Herrington</author>
<title>Podcasting Hacks</title>
<publisher>O&#39;Reilly</publisher>
</book>
</books>
 
1.DOMDocument方法
<?php
 $doc = new DOMDocument();
 $doc->load( &#39;books.xml&#39; );
 $books = $doc->getElementsByTagName( "book" );
 foreach( $books as $book )
 {
 $authors = $book->getElementsByTagName( "author" );
 $author = $authors->item(0)->nodeValue;
  
 $publishers = $book->getElementsByTagName( "publisher" );
 $publisher = $publishers->item(0)->nodeValue;
  
 $titles = $book->getElementsByTagName( "title" );
 $title = $titles->item(0)->nodeValue;
  
 echo "$title - $author - $publisher\n";
 echo "<br>";
 }
 ?>
 
2.用 SAX 解析器读取 XML
 
<?php
 $g_books = array();
 $g_elem = null;
  
 function startElement( $parser, $name, $attrs ) 
 {
 global $g_books, $g_elem;
 if ( $name == &#39;BOOK&#39; ) $g_books []= array();
 $g_elem = $name;
 }
  
 function endElement( $parser, $name ) 
 {
 global $g_elem;
 $g_elem = null;
 }
  
 function textData( $parser, $text )
 {
 global $g_books, $g_elem;
 if ( $g_elem == &#39;AUTHOR&#39; ||
 $g_elem == &#39;PUBLISHER&#39; ||
 $g_elem == &#39;TITLE&#39; )
 {
 $g_books[ count( $g_books ) - 1 ][ $g_elem ] = $text;
 }
 }
  
 $parser = xml_parser_create();
  
 xml_set_element_handler( $parser, "startElement", "endElement" );
 xml_set_character_data_handler( $parser, "textData" );
  
 $f = fopen( &#39;books.xml&#39;, &#39;r&#39; );
  
 while( $data = fread( $f, 4096 ) )
 {
 xml_parse( $parser, $data );
 }
  
 xml_parser_free( $parser );
  
 foreach( $g_books as $book )
 {
 echo $book[&#39;TITLE&#39;]." - ".$book[&#39;AUTHOR&#39;]." - ";
 echo $book[&#39;PUBLISHER&#39;]."\n";
 }
 ?>
 
3.用正则表达式解析 XML
 
<?php
 $xml = "";
 $f = fopen( &#39;books.xml&#39;, &#39;r&#39; );
 while( $data = fread( $f, 4096 ) ) {
     $xml .= $data; 
 }
 fclose( $f );
  
 preg_match_all( "/\<book\>(.*?)\<\/book\>/s", $xml, $bookblocks );
  
 foreach( $bookblocks[1] as $block )
 {
 preg_match_all( "/\<author\>(.*?)\<\/author\>/", $block, $author );
 preg_match_all( "/\<title\>(.*?)\<\/title\>/",   $block, $title );
 preg_match_all( "/\<publisher\>(.*?)\<\/publisher\>/", $block, $publisher );
 echo( $title[1][0]." - ".$author[1][0]." - ".$publisher[1][0]."\n" );
 }
 ?>
 
4.解析XML到数 组
 
<?php
     $data = "<root><line /><content language=\"gb2312\">简单的XML数据</content></root>";
     $parser = xml_parser_create();                        //创建解析器
     xml_parse_into_struct($parser, $data, $values, $index);    //解析到数组
     xml_parser_free($parser);                            //释放资源
      
     //显示数组结构
     echo "\n索引数组\n";
     print_r($index);
     echo "\n数据数组\n";
     print_r($values);
 ?>
 
5.检查XML是否有效
 
<?php
     //创建XML解析器
     $xml_parser = xml_parser_create();
  
     //使用大小写折叠来保证能在元素数组中找到这些元素名称
     xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true);
  
     //读取XML文件
     $xmlfile = "bb.xml";
     if (!($fp = fopen($xmlfile, "r")))
     {
         die("无法读取XML文件$xmlfile");
     }
  
     //解析XML文件
     $has_error = false;            //标志位
     while ($data = fread($fp, 4096))
     {
         //循环地读入XML文档,只到文档的EOF,同时停止解析
         if (!xml_parse($xml_parser, $data, feof($fp)))
         {
             $has_error = true;
             break;
         }
     }
  
     if($has_error)
     { 
         echo "该XML文档是错误的!<br />";
  
         //输出错误行,列及其错误信息
         $error_line   = xml_get_current_line_number($xml_parser);
         $error_row   = xml_get_current_column_number($xml_parser);
         $error_string = xml_error_string(xml_get_error_code($xml_parser));
  
         $message = sprintf("[第%d行,%d列]:%s", 
                         $error_line,
                         $error_row,
                         $error_string);
         echo $message;
     }
     else
     {
         echo "该XML文档是结构良好的。";
     }
      
     //关闭XML解析器指针,释放资源
     xml_parser_free($xml_parser);
 ?>
6.可用于精确的读取XML
test.xml
<?xml version="1.0" encoding="UTF-8" ?>
     <SBMP_MO_MESSAGE>
         <CONNECT_ID>100</CONNECT_ID>
         <MO_MESSAGE_ID>123456</MO_MESSAGE_ID>
         <RECEIVE_DATE>20040605</RECEIVE_DATE>
         <RECEIVE_TIME>153020</RECEIVE_TIME>
         <GATEWAY_ID>1</GATEWAY_ID>
         <VALID>1</VALID>
         <CITY_CODE>010</CITY_CODE>
         <CITY_NAME>北京</CITY_NAME>
         <STATE_CODE>010</STATE_CODE>
         <STATE_NAME>北京</STATE_NAME>
         <TP_PID>0</TP_PID>
         <TP_UDHI>0</TP_UDHI>
         <MSISDN>15933626501</MSISDN>
         <MESSAGE_TYPE>8</MESSAGE_TYPE>
         <MESSAGE>5618常年供应苗木,品种有玉兰、黄叶杨等。联系人:张三,电话:1234567890。</MESSAGE>
         <LONG_CODE>100</LONG_CODE>
         <SERVICE_CODE>9588</SERVICE_CODE>
     </SBMP_MO_MESSAGE>
 test.php:
 <?php
 $myData = array();
 $file = file_get_contents("test.xml");
 if(strpos($file, &#39;<?xml&#39;) > -1) {
         try {
             //加载解析xml
             $xml = simplexml_load_string($file);
             if($xml) {
                 //echo $this->result;
                 //获取节点值
                 $CONNECT_ID = $xml->CONNECT_ID;
                 $MO_MESSAGE_ID = $xml->MO_MESSAGE_ID;
                 $RECEIVE_DATE = $xml->RECEIVE_DATE;
                 $RECEIVE_TIME = $xml->RECEIVE_TIME;
                 $GATEWAY_ID = $xml->GATEWAY_ID;
                 $VALID = $xml->VALID;
                 $CITY_CODE = $xml->CITY_CODE;
                 $CITY_NAME = $xml->CITY_NAME;
                 $STATE_CODE = $xml->CITY_CODE;
                 $STATE_NAME = $xml->STATE_NAME;
                 $TP_PID = $xml->TP_PID;
                 $TP_UDHI = $xml->TP_UDHI;
                 $MSISDN = $xml->MSISDN;
                 $MESSAGE_TYPE = $xml->MESSAGE_TYPE;
                 $MESSAGE = $xml->MESSAGE;//短信
                 $LONG_CODE = $xml->LONG_CODE;
                 $SERVICE_CODE = $xml->SERVICE_CODE;
                 preg_match("/(561)\d{1,2}/", $MESSAGE, $code);
                 switch($code[0]) {
                     case 5618 :
                         $myData[message] = $MESSAGE;
                         break;
                     default :
                         $myData[] = &#39;没有短消息。&#39;;
                         break;
                     }
                      
                 } else {
                     echo "加载xml文件错误。";
                 }
              
         } catch(exception $e){
             print_r($e);
         }
  
 } else {
     echo "没有该XML文件。";
 }
  
 echo "<pre class="brush:php;toolbar:false">";
 print_r($myData);
 echo "<hr>";
 echo $myData[message];
 ?>

2.PHP中的生成XML文件的4种方法

【前言】
使用PHP怎么创建XML文件呢?
一直以来都是使用别人封装好的类,没有自己尝试过,难得放几天假,于是自己总结了下。使用PHP生成XML文件的4种常见方法如下:
【XML文件内容】
<?xml version="1.0" encoding="utf-8"?>
<article>
    <item>
        <title size="1">title1</title>
        <content>content1</content>
        <pubdate>2009-10-11</pubdate>
    </item>
    <item>
        <title size="1">title2</title>
        <content>content2</content>
        <pubdate>2009-11-11</pubdate>
    </item>
</article>
【直接生成字符串】
方法1:使用纯粹的PHP代码生成字符串,并把这个字符串写入一个以XML为后缀的文件。这是最原始的生成XML的方法,不过有效!
PHP代码如下:
<?PHP
$data_array = array(
    array(
    &#39;title&#39; => &#39;title1&#39;,
    &#39;content&#39; => &#39;content1&#39;,
        &#39;pubdate&#39; => &#39;2009-10-11&#39;,
    ),
    array(
    &#39;title&#39; => &#39;title2&#39;,
    &#39;content&#39; => &#39;content2&#39;,
    &#39;pubdate&#39; => &#39;2009-11-11&#39;,
    )
);
$title_size = 1;
  
$xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$xml .= "<article>\n";
  
foreach ($data_array as $data) {
    $xml .= create_item($data[&#39;title&#39;], $title_size, $data[&#39;content&#39;], $data[&#39;pubdate&#39;]);
}
  
$xml .= "</article>\n";
  
echo $xml;
  
//  创建XML单项
function create_item($title_data, $title_size, $content_data, $pubdate_data) {
    $item = "<item>\n";
    $item .= "<title size=\"" . $title_size . "\">" . $title_data . "</title>\n";
    $item .= "<content>" . $content_data . "</content>\n";
    $item .= " <pubdate>" . $pubdate_data . "</pubdate>\n";
    $item .= "</item>\n";
  
    return $item;
}
  
  
?>
【DomDocument】
方法2:使用DomDocument生成XML文件
创建节点使用createElement方法,
创建文本内容使用createTextNode方法,
添加子节点使用appendChild方法,
创建属性使用createAttribute方法
PHP代码如下:
<?PHP
$data_array = array(
    array(
    &#39;title&#39; => &#39;title1&#39;,
    &#39;content&#39; => &#39;content1&#39;,
        &#39;pubdate&#39; => &#39;2009-10-11&#39;,
    ),
    array(
    &#39;title&#39; => &#39;title2&#39;,
    &#39;content&#39; => &#39;content2&#39;,
    &#39;pubdate&#39; => &#39;2009-11-11&#39;,
    )
);
  
//  属性数组
$attribute_array = array(
    &#39;title&#39; => array(
    &#39;size&#39; => 1
    )
);
  
//  创建一个XML文档并设置XML版本和编码。。
$dom=new DomDocument(&#39;1.0&#39;, &#39;utf-8&#39;);
  
//  创建根节点
$article = $dom->createElement(&#39;article&#39;);
$dom->appendchild($article);
  
foreach ($data_array as $data) {
    $item = $dom->createElement(&#39;item&#39;);
    $article->appendchild($item);
  
    create_item($dom, $item, $data, $attribute_array);
}
  
echo $dom->saveXML();
  
function create_item($dom, $item, $data, $attribute) {
    if (is_array($data)) {
        foreach ($data as $key => $val) {
            //  创建元素
            $$key = $dom->createElement($key);
            $item->appendchild($$key);
  
            //  创建元素值
            $text = $dom->createTextNode($val);
            $$key->appendchild($text);
  
            if (isset($attribute[$key])) {  //  如果此字段存在相关属性需要设置
                foreach ($attribute[$key] as $akey => $row) {
                    //  创建属性节点
                    $$akey = $dom->createAttribute($akey);
                    $$key->appendchild($$akey);
  
                    // 创建属性值节点
                    $aval = $dom->createTextNode($row);
                    $$akey->appendChild($aval);
                }
            }   //  end if
        }
    }   //  end if
}   //  end function
?>
【XMLWriter】
方法3:使用XMLWriter类创建XML文件
此方法在PHP 5.1.2后有效
另外,它可以输出多种编码的XML,但是输入只能是utf-8
PHP代码如下:
<?PHP
$data_array = array(
    array(
    &#39;title&#39; => &#39;title1&#39;,
    &#39;content&#39; => &#39;content1&#39;,
        &#39;pubdate&#39; => &#39;2009-10-11&#39;,
    ),
    array(
    &#39;title&#39; => &#39;title2&#39;,
    &#39;content&#39; => &#39;content2&#39;,
    &#39;pubdate&#39; => &#39;2009-11-11&#39;,
    )
);
  
//  属性数组
$attribute_array = array(
    &#39;title&#39; => array(
    &#39;size&#39; => 1
    )
);
  
$xml = new XMLWriter();
$xml->openUri("php://output");  //  输出方式,也可以设置为某个xml文件地址,直接输出成文件
$xml->setIndentString(&#39;  &#39;);
$xml->setIndent(true);
  
$xml->startDocument(&#39;1.0&#39;, &#39;utf-8&#39;);    //  开始创建文件
//  根结点
$xml->startElement(&#39;article&#39;);
  
foreach ($data_array as $data) {    
    $xml->startElement(&#39;item&#39;);
  
    if (is_array($data)) {
        foreach ($data as $key => $row) {
            $xml->startElement($key);
  
            if (isset($attribute_array[$key]) && is_array($attribute_array[$key])) {
                foreach ($attribute_array[$key] as $akey => $aval) {    //  设置属性值
                    $xml->writeAttribute($akey, $aval);
                }
  
            }
  
            $xml->text($row);   //  设置内容
            $xml->endElement(); // $key
        }
  
    }
    $xml->endElement(); //  item
}
  
$xml->endElement(); //  article
$xml->endDocument();
  
$xml->flush();
?>
【SimpleXML】
方法4:使用SimpleXML创建XML文档
 
<?PHP
$data_array = array(
    array(
    &#39;title&#39; => &#39;title1&#39;,
    &#39;content&#39; => &#39;content1&#39;,
        &#39;pubdate&#39; => &#39;2009-10-11&#39;,
    ),
    array(
    &#39;title&#39; => &#39;title2&#39;,
    &#39;content&#39; => &#39;content2&#39;,
    &#39;pubdate&#39; => &#39;2009-11-11&#39;,
    )
);
  
//  属性数组
$attribute_array = array(
    &#39;title&#39; => array(
    &#39;size&#39; => 1
    )
);
  
$string = <<<XML
<?xml version=&#39;1.0&#39; encoding=&#39;utf-8&#39;?>
<article>
</article>
XML;
  
$xml = simplexml_load_string($string);
  
foreach ($data_array as $data) {
    $item = $xml->addChild(&#39;item&#39;);
    if (is_array($data)) {
        foreach ($data as $key => $row) {
            $node = $item->addChild($key, $row);
  
            if (isset($attribute_array[$key]) && is_array($attribute_array[$key])) {
                foreach ($attribute_array[$key] as $akey => $aval) {    //  设置属性值
                    $node->addAttribute($akey, $aval);
                }
            }
        }
    }
}
echo $xml->asXML();
?>

3.PHP中的XML解析的5种方法 

【使用DomDocument解析】
<?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 &#39;天气:&#39;, $condition, &#39;<br />&#39;;
echo &#39;温度:&#39;, $temp_c, &#39;<br />&#39;;
  
function get_utf8_string($content) {    //  将一些字符转化成utf8格式
    $encoding = mb_detect_encoding($content, array(&#39;ASCII&#39;,&#39;UTF-8&#39;,&#39;GB2312&#39;,&#39;GBK&#39;,&#39;BIG5&#39;));
    return  mb_convert_encoding($content, &#39;utf-8&#39;, $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档案的节点,可以想像成游标走过整份文件的节点,并抓取需要的内容。
 
<?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 = &#39;&#39;;
$temp_c = &#39;&#39;;
while ($xml->read()) {
//      echo $xml->name, "==>", $xml->depth, "<br>";
      if (!empty($condition) && !empty($temp_c)) {
          break;
      }
      if ($xml->name == &#39;condition&#39; && empty($condition)) {  //  取第一个condition
            $condition = $xml->getAttribute(&#39;data&#39;);
      }
  
      if ($xml->name == &#39;temp_c&#39; && empty($temp_c)) {    //  取第一个temp_c
          $temp_c = $xml->getAttribute(&#39;data&#39;);
      }
  
      $xml->read();
}
  
$xml->close();
echo &#39;天气:&#39;, $condition, &#39;<br />&#39;;
echo &#39;温度:&#39;, $temp_c, &#39;<br />&#39;;
我们只是需要取第一个condition和第一个temp_c,于是遍历所有的节点,将遇到的第一个condition和第一个temp_c写入变量,最后输出。
【DOMXPath】
这种方法需要使用DOMDocument对象创建整个文档的结构,
<?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 &#39;天气:&#39;, $condition, &#39;<br />&#39;;
echo &#39;温度:&#39;, $temp_c, &#39;<br />&#39;;
  
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 不同,使用例如 === 的运算符时要注意。
 
<?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 &#39;天气:&#39;, $vals[$index[&#39;CONDITION&#39;][0]][&#39;attributes&#39;][&#39;DATA&#39;], &#39;<br />&#39;;
echo &#39;温度:&#39;, $vals[$index[&#39;TEMP_C&#39;][0]][&#39;attributes&#39;][&#39;DATA&#39;], &#39;<br />&#39;;
【Simplexml】
此方法在PHP5中可用
这个在google的官方文档中有相关的例子,如下:
 
// 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[&#39;city&#39;]) ? &#39;shenzhen&#39; : $_GET[&#39;city&#39;];
$content = file_get_contents("http://www.google.com/ig/api?weather=$city&hl=zh-cn");
$content || die("No such city&#39;s data");
$content = mb_convert_encoding($content, &#39;UTF-8&#39;, &#39;GBK&#39;);
$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=&#39;http://www.google.com/ig{$icon}&#39;/> {$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=&#39;http://www.google.com/ig{$icon}&#39; /><br />\r\n";
}
  
header(&#39;Content-type: text/html; Charset: utf-8&#39;);
print $html;
?>
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.