现在的位置: 首页 > 综合 > 正文

SimpleXML学习笔记

2013年07月06日 ⁄ 综合 ⁄ 共 10550字 ⁄ 字号 评论关闭

SimpleXML学习笔记  

simplexml 使用实例

搞了几天php处理xml文件,终于有点头绪,记录下来分享一下。
simplexml 是php处理xml文件的一个方法,另一个是dom处理,这里只说simplexml。
目前php处理xml用的比较多,比较成熟的还是dom。但dom在速度和代码量上还是比较受人诟病的。

simplexml的有些函数需要比较高版本的php,建议是php5.2以上。

一,新建xml

方法1(普通新建文件):

$fp=fopen('111.xml','w');
 $xmlContent='<?xml version="1.0" encoding="utf-8" ?> ';
 $xmlContent.='<navlist>';
 $xmlContent.='<nav id="1">';
 $xmlContent.='<name>我我我</nname> ';
 $xmlContent.='<color>#000000</ncolor> ';
 $xmlContent.='</nav>';
 
 $xmlContent.='<nav id="2">';

 $xmlContent.='<name>你你你</nname> ';
 $xmlContent.='<color>#ffffff</ncolor> ';
 $xmlContent.='</nav>';
 
 $xmlContent.='<nav id="3">';
 $xmlContent.='<nname>他他他</nname> ';
 $xmlContent.='<ncolor>#cccccc</ncolor> ';
 $xmlContent.='</nav>';
 
 $xmlContent.='</navlist>';
 fwrite($fp,$xmlContent);
 fclose($fp);

 

方法2(使用simplexml新建):

$fp=fopen(111.xml','w');
 $xmlContent='<?xml version="1.0" encoding="utf-8" ?><navlist></navlist>';
 fwrite($fp,$xmlContent);
 fclose($fp);


 $xml=simplexml_load_file('111.xml'); 


 $app=$xml->addChild('nav');
 $app->addAttribute('id',"1");
 $app->addChild('name','我我我');
 $app->addChild('color','#000000');

 
 $app=$xml->addChild('nav');
 $app->addAttribute('id',"2");
 $app->addChild('name','你你你');
 $app->addChild('color','#ffffff);
 
 $app=$xml->addChild('nav');
 $app->addAttribute('id',"3");
 $app->addChild('name','他他他');
 $app->addChild('color','#cccccc); 


 $xml->asXML('111.xml');

 

可以看到第一种方法其实只是普通的写入文件,第二种方法才是使用simplexml新建xml文件,但为什么我要把第一种普通方法放前面呢?因为本人测试了一下两种方法的运行时间,发现第一种方法使用的时间更少,所以建议使用普通的新建文件方法新建xml文件就行了!

新建的文件结构如下:

<?xml version="1.0" encoding="utf-8"?>
<navlist>
 <nav id="1">
  <name>我我我</nname>
  <color>#000000</ncolor>
 </nav>
 <nav id="2">
  <name>你你你</nname>
  <color>#ffffff</ncolor>
 </nav>
 <nav id="3">
  <name>他他他</nname>
  <color>#cccccc</ncolor>
 </nav>
</navlist>

 

二,读取xml

     if($xml=simplexml_load_file('111.xml')){
          foreach($xml->nav as $list){
                       $value[]=get_object_vars($list); 
          }
     }else{
              echo('load xml error!');
     }

get_object_vars函数是把对象转化为数组,这样$value就是一个Php的普通数组了,大家可以print_r一下这个数组,Php数组的读取就不用我说了吧。

三,修改xml

1,新建节点

 $xml=simplexml_load_file('111.xml'); 
 $app=$xml->addChild('nav');
 $app->addAttribute('id',"4");
 $app->addChild('name','它它它');
 $app->addChild('color','#000000');
 $xml->asXML(111.xml');

将追加作为最后一个节点

 

2,修改节点

 $xml=simplexml_load_file('111.xml'); 

 $xg=$xml->xpath("/navlist/nav[@id=‘3’]");  
 $xg[0]->name="他啊他啊";
 $xg[0]->color="#444444";
 $xml->asXML(111.xml');

修改了nav属性id为3的节点

 

3,删除节点

删除节点用unset函数就行,但要删除指定节点比较麻烦,删除指定节点只能使用节点的索引值。

比如删除第二个节点(id为2的):

$xml=simplexml_load_file('111.xml'); 

unset($xml->nav[1]);

$xml->asXML(111.xml');

索引从0开始,所以第二个节点的索引是1。

如果想通过指定的属性删除,则需要循环所有节点获取指定属性的节点索引
如下:

$xml=simplexml_load_file('111.xml'); 

$i=0;

 foreach($xml as $dup){
  $sc=$dup->attributes();
  if($sc['id']==2){
   unset($xml->nav[$i]);
  }
  $i++;
 }

$xml->asXML('111.xml');

 

四,删除xml

if(file_exists('111.xml')){
    unlink('111.xml');
 }

--------------------------------------------------------------------------------------------------------------------------------------------------

相关的三个代码文件:

data.dtd  定义XML合法词汇
data.xml  XML文档
index.php 主索引文件

--------------------------------------------------------------------------------

代码如下:

data.dtd

  1. <!ELEMENT friendLinkLib (friendLink)>  
  2. <!ELEMENT friendLink (name, url, info, logoPath, qqMsn)>  
  3. <!ELEMENT name (#PCDATA)>  
  4. <!ELEMENT url (#PCDATA)>  
  5. <!ELEMENT info (#PCDATA)>  
  6. <!ELEMENT logoPath (#PCDATA)>  
  7. <!ELEMENT qqMsn (#PCDATA)>  
  8. <!ATTLIST friendLink id CDATA #REQUIRED>  
  9. <!ATTLIST friendLink isPass (0|1) "0">  
  10. <!ATTLIST friendLink orderId CDATA #IMPLIED>  
  11. <!ATTLIST friendLink isImage (0|1) "1">  
  12. <!ATTLIST friendLink isDisplay (0|1) "1">  
  13. <!ATTLIST friendLink position (supe|bbs|home) "supe">  

 

data.xml

  1. <?xml version="1.0" encoding="gbk"?>  
  2. <!DOCTYPE FriendLink SYSTEM "http://localhost/eg/data.dtd">  
  3. <friendLinkLib>  
  4.     <friendLink orderId="0" id="1" position="supe">  
  5.         <name>邯城正午</name>  
  6.         <url>http://www.cityxii.cn</url>  
  7.         <info>邯郸人的网上家园</info>  
  8.         <logoPath>http://localhost/images/xmllogo.jpg</logoPath>  
  9.         <qqMsn>QQ:250660802</qqMsn>  
  10.     </friendLink>  
  11.     <friendLink orderId="1" id="2" position="supe">  
  12.         <name>邯城社区</name>  
  13.         <url>http://www.cityxii.cn</url>  
  14.         <info>邯郸人的网上家园</info>  
  15.         <logoPath>http://localhost/images/xmllogo.jpg</logoPath>  
  16.         <qqMsn>QQ:250660802</qqMsn>  
  17.     </friendLink>  
  18. </friendLinkLib>  

 

index.php

 

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. <html>  
  2. <head>  
  3. <meta http-equiv="Content-Type" Content="text/html; charset=gbk" />  
  4. <title>使用SimpleXML解析xml文件</title></head>  
  5. <body>  
  6. <?php   
  7. include 'FL_inc/friendLink.inc.php';  
  8. $xml    = simplexml_load_file("./FL_data/data.xml");  
  9. /* 
  10.  * 1. 访问节点值,并执行转码 
  11. echo 'Print The Content of node: '; 
  12. $name   = $xml->friendLink->name; 
  13. echo iconv('utf-8','gbk',$name),'<br />'; 
  14.  * 2. 访问属性值,注意:只有中文需要转码,数字和英文以及英文标点无需转码 
  15. echo 'Print The Att of root node: '; 
  16. //echo iconv('utf-8', 'gbk', $xml->friendLink[1]['id']); 
  17. echo $xml->friendLink[1]['id']; 
  18. echo '<hr />END<hr />'; 
  19. */  
  20. /* 
  21.  * 3. 增加节点,并且设置节点值,以及节点属性。 
  22.  *      注意:增加值的时候需要转码,同样只是中文需要转码。因为页面index.php的编码是GBK,所以要转成utf-8 
  23. $newLink    = $xml->addChild('friendLink'); 
  24. $newLink->addChild('name', iconv('gbk','utf-8','众里寻他千百度')); 
  25. $newLink->addChild('url', 'http://www.baidu.com'); 
  26. $newLink->addChild('info', 'Baidudu'); 
  27. $newLink->addChild('logoPath', 'd:/image.jpg'); 
  28. $newLink->addChild('qqMsn', 'MSN:jj@yahoo.cn'); 
  29. $newLink->addAttribute('id','3'); 
  30. $newLink->addAttribute('orderId','3'); 
  31. */  
  32. /* 
  33.  * 4. 修改节点以及属性的值,同样中文要注意转码 
  34. $xml->friendLink[2]->name = iconv('gbk','utf-8','新浪网');       // 设置节点3 name的值为新浪网。注意索引从0开始 
  35. $xml->friendLink[2]['id']    = 3;    //  节点3的friendLink元素的属性(id=3)。 
  36. */  
  37. /* 
  38.  * 5. 遍历xml文档 
  39.  * 5.1 遍历所有一级节点的属性值以及内容 
  40. foreach($xml->friendLink as $link){ 
  41.     echo '<hr />'; 
  42.     echo $link['id'],'<br />'; 
  43.     echo $link['orderId'],'<br />'; 
  44.     foreach($link as $key=>$value){ 
  45.         echo $key,' : ',iconv('utf-8','gbk',$value),'<br />'; 
  46.     } 
  47. */  
  48. /* 5.2 遍历XML文档中某一个节点的值,比如打印出所有元素的name节点的值 
  49. foreach($xml->xpath('//info') as $value) { 
  50.     echo minIconv($value),'<br />'; 
  51. */  
  52. /* 5.3 遍历出某个元素的所有子节点值 
  53. foreach($xml->friendLink[1]->children() as $field){ 
  54.     echo minIconv($field),'<br />'; 
  55. foreach($xml->children() as $var){ 
  56. //  echo $var['id'],'<br />'; 
  57. //  echo minIconv($var->name),'<br />'; 
  58.     echo $var->getName(),'<br />'; // 获得当前节点/元素的名称 
  59. */  
  60. /* 5.4 遍历XML文档中某一个节点的属性,比如打印出第二个元素的所有属性值 
  61. foreach($xml->friendLink[1]->attributes() as $key=>$value){ 
  62.     echo $key,' = ',$value,'<br />'; 
  63. */  
  64. // 6. 保存内容到xml文档  
  65. //$xml->asXML('FL_data/data.xml');  
  66. /* 
  67. $namespace  = $xml->getDocNamespaces(); 
  68. var_dump($namespace); 
  69. */  
  70. ?>  
  71. </body>  
  72. </html>  

 

 

注意:

data.xml文件是GBK编码

index.php文件是GBK编码

 

但是simpleXML解析出来的是UTF-8编码

所以就使用到iconv()函数

 

用到一个简写的转换函数minIconv()

 

function minIconv($str, $in='utf-8', $out='gbk'){
    $str    = iconv($in, $out, $str);
    return $str;
}

-----------------------------------------------------------

            $data = array();
            $data['node_type'] = 3;
            $data['node_name'] = (string)$targetNode->node_name[0];
            $data['node_id'] = (string)$targetNode->target_node->node_id[0];
            echo json_encode(array('success' => true,'data' => $data));

--------------------------------------------------------------------------------------------------------------------------------------------------

http://blog.csdn.net/guoguo1980/archive/2008/05/12/2436318.aspx

SimpleXML

介绍

SimpleXML提供了一种简单,直观的方法来处理XML。它只有一个单一类型的类,三个函数和六个方法。

使用SimpleXML

SimpleXMLElement 类是这个扩展中所有操作的核心类。可以用new关键字直接创建这种类,或是使用simplexml_load_file()或 simplexml_load_string()函数返回这种类。本文将使用清单7-1的XML文档来说明如何使用SimpleXML,将此文档命名为 sml.xml。

清单7-1 sml.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD
    DocBook XML V4.1.2//EN
    "
  3. "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
  4. <book lang="en">
  5.     <bookinfo>
  6.         <title>SimpleXML in PHP 5</title>
  7.         <author>
  8.             <firstname>Rob</firstname>
  9.             <surname>Richards</surname>
  10.         </author>
  11.         <copyright>
  12.             <year>2005</year>
  13.             <holder>Rob Richards</holder>
  14.         </copyright>
  15.     </bookinfo>
  16.     <preface>
  17.         <title>Using SimpleXML</title>
  18.         <para>An example DOM Tree using DocBook.</para>
  19.     </preface>
  20.     <chapter id="navigation">
  21.         <title>Accessing Elements</title>
  22.         <para>Elements are accessed as properties</para>
  23.         <para>
  24.         <![CDATA[
  25.         <?php
  26.         $data = '<?xml version="1.0"?>
  27.         <root>content</root>';
  28.         $sxe = simplexml_load_string($data);
  29.         var_dump($sxe);
  30.         ?>
  31.         ]]>
  32.         </para>
  33.     </chapter>
  34. </book>

创建一个SimpleXMLElement对象

使用new关键字创建

  1. $xml = "<root><node1>Content</node1></root>";
  2. $sxe = new SimpleXMLElement($xml);//SimpleXMLElement
    Object ( [node1] => Content )

使用simplexml_load_string()创建

  1. $xml = "<root><node1>Content</node1></root>";
  2. $sxe = simplexml_load_string($xml);//SimpleXMLElement
    Object ( [node1] => Content )

如何选择这两种创建SimpleXMLElement的方法呢?simplexml_load_string()提供了更多的函数,比如控制解析选项的能力。如果不需要这些额外的函数的话就可以凭个人爱好选择一种方法。

使用simplexml_load_file()从一个URI创建

  1. $sxe = simplexml_load_file("filename.xml");

simplexml_load_string()和simplexml_load_file()都有一个必需的参数和可选的参数。从PHP5.1开始simplexml_load_file()多了一个用来控制解析行为的第三个参数。

  1. /* Prototype for PHP 5.0 */
  2. simplexml_load_file(string data [string class_name])
  3. /* Prototype for PHP 5.1 */
  4. simplexml_load_file(string data [string class_name [int options]])

保存XML数据

与DOM扩展一样,SimpleXML也提供了一个用来输出XML内容的方法asXML()。可以用这个方法以字符串或文件形式输出这个文档或文档中的某个节点。

  1. $xml = "<root><node1>content</node1></root>";
  2. $sxe = new SimpleXMLElement($xml);
  3. print $sxe->asXML();
  4. $sxe->asXML('test.xml');

输出:

  1. <?xml version="1.0"?>
  2. <root><node1>content</node1></root>

访问元素节点

在SimpleXML中,可以直接通过元素的名称来访问特定的元素。

访问元素

当一个文档被载入SimpleXML时,文档被看成是一个SimpleXML对象,文档中的所有元素都被看成是该对象的属性。

  1. <?php
  2. $book = simplexml_load_file('sxml.xml');
  3. /* Access the bookinfo child element of the book element */
  4. $bookinfo = $book->bookinfo;
  5. /* Access the title child element from the bookinfo element */
  6. $title = $bookinfo->title;
  7. ?>

如果使用DOM来访问title,代码如下

  1. $dom = new DOMDocument();
  2. $dom->load('sxml.xml');
  3. $book = $dom->documentElement;
  4. foreach($book->childNodes as $node) {
  5.     if ($node->nodeName == "bookinfo") {
  6.         foreach($node->childNodes as $child) {
  7.             if ($child->nodeName == "title") {
  8.                 $node = $child;
  9.                 break 2;
  10.             }
  11.         }
  12.     }
  13. }
  14. if ($node) {
  15.     $title = $node;
  16. }

显然SimpleXML对的起它的名字。

访问内容

  1. <?php
  2. $book = simplexml_load_file('sxml.xml');
  3. $bookinfo = $book->bookinfo;
  4. $title = $bookinfo->title;
  5. /* Object examined with var_dump */
  6. var_dump($title);
  7. /* Using print with element containing text-only content */
  8. print "Title: ".$title."\n";
  9. $author = $bookinfo->author;
  10. /* Object examined with var_dump */
  11. var_dump($author);
  12. /* Using print with element containing child elements */
  13. print "Author: ".$author."\n";

抱歉!评论已关闭.