欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  php教程

PHP读取XML

程序员文章站 2022-05-17 08:15:58
...
php读取xml

1.php代码

books.xml文件:
 
<books>
<book>
<author>Jack Herrington</author>
<title>PHP Hacks</title>
<publisher>O'Reilly</publisher>
</book>
<book>
<author>Jack Herrington</author>
<title>Podcasting Hacks</title>
<publisher>O'Reilly</publisher>
</book>
</books>
 
1.DOMDocument方法
<?php
 $doc = new DOMDocument();
 $doc->load( 'books.xml' );
 $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 == 'BOOK' ) $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 == 'AUTHOR' ||
 $g_elem == 'PUBLISHER' ||
 $g_elem == 'TITLE' )
 {
 $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( 'books.xml', 'r' );
  
 while( $data = fread( $f, 4096 ) )
 {
 xml_parse( $parser, $data );
 }
  
 xml_parser_free( $parser );
  
 foreach( $g_books as $book )
 {
 echo $book['TITLE']." - ".$book['AUTHOR']." - ";
 echo $book['PUBLISHER']."\n";
 }
 ?>
 
3.用正则表达式解析 XML
 
<?php
 $xml = "";
 $f = fopen( 'books.xml', 'r' );
 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, '<?xml') > -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[] = '没有短消息。';
                         break;
                     }
                      
                 } else {
                     echo "加载xml文件错误。";
                 }
              
         } catch(exception $e){
             print_r($e);
         }
  
 } else {
     echo "没有该XML文件。";
 }
  
 echo "<pre>";
 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(
    'title' => 'title1',
    'content' => 'content1',
        'pubdate' => '2009-10-11',
    ),
    array(
    'title' => 'title2',
    'content' => 'content2',
    'pubdate' => '2009-11-11',
    )
);
$title_size = 1;
  
$xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$xml .= "<article>\n";
  
foreach ($data_array as $data) {
    $xml .= create_item($data['title'], $title_size, $data['content'], $data['pubdate']);
}
  
$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(
    'title' => 'title1',
    'content' => 'content1',
        'pubdate' => '2009-10-11',
    ),
    array(
    'title' => 'title2',
    'content' => 'content2',
    'pubdate' => '2009-11-11',
    )
);
  
//  属性数组
$attribute_array = array(
    'title' => array(
    'size' => 1
    )
);
  
//  创建一个XML文档并设置XML版本和编码。。
$dom=new DomDocument('1.0', 'utf-8');
  
//  创建根节点
$article = $dom->createElement('article');
$dom->appendchild($article);
  
foreach ($data_array as $data) {
    $item = $dom->createElement('item');
    $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(
    'title' => 'title1',
    'content' => 'content1',
        'pubdate' => '2009-10-11',
    ),
    array(
    'title' => 'title2',
    'content' => 'content2',
    'pubdate' => '2009-11-11',
    )
);
  
//  属性数组
$attribute_array = array(
    'title' => array(
    'size' => 1
    )
);
  
$xml = new XMLWriter();
$xml->openUri("php://output");  //  输出方式,也可以设置为某个xml文件地址,直接输出成文件
$xml->setIndentString('  ');
$xml->setIndent(true);
  
$xml->startDocument('1.0', 'utf-8');    //  开始创建文件
//  根结点
$xml->startElement('article');
  
foreach ($data_array as $data) {    
    $xml->startElement('item');
  
    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(
    'title' => 'title1',
    'content' => 'content1',
        'pubdate' => '2009-10-11',
    ),
    array(
    'title' => 'title2',
    'content' => 'content2',
    'pubdate' => '2009-11-11',
    )
);
  
//  属性数组
$attribute_array = array(
    'title' => array(
    'size' => 1
    )
);
  
$string = <<<XML
<?xml version='1.0' encoding='utf-8'?>
<article>
</article>
XML;
  
$xml = simplexml_load_string($string);
  
foreach ($data_array as $data) {
    $item = $xml->addChild('item');
    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 '天气:', $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档案的节点,可以想像成游标走过整份文件的节点,并抓取需要的内容。
 
<?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对象创建整个文档的结构,
<?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 不同,使用例如 === 的运算符时要注意。
 
<?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的官方文档中有相关的例子,如下:
 
// 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;
?>
相关标签: PHP读取XML