设为首页 收藏本站
查看: 1111|回复: 0

[经验分享] PHP通过SimpleXML访问xml文档 (二)

[复制链接]
累计签到:1365 天
连续签到:1 天
发表于 2018-12-19 14:11:58 | 显示全部楼层 |阅读模式
  修改内容
  利用SimpleXML修改元素内容非常方便,你可以改变或移除树中的某个元素,但是不能直接在树中添加一个元素。要添加一个元素,可以使用DOM的互操作性:

  •   $xml = "content";
  •   $sxe = new SimpleXMLElement($xml);
  •   $dom = dom_import_simplexml($sxe);
  •   $dom->appendChild(new DOMElement("node2", "content2"));
  •   print $sxe->asXML();
  输出:

  •   
  •   contentcontent2
  编辑文本内容
  可以利用SimpleXML的属性赋值方法来直接编辑一个元素的内容,要主意的是如果文档中有多个元素名一样的元素,如果没有使用索引来指定要编辑哪个元素时PHP将发出一个警告。如:

  •   $book = simplexml_load_file('sxml.xml');
  •   /* Modify an unspecified para element where multiple para elements exist */
  •   $book->chapter->para = "Removed CDATA";
  输出:
  Warning: main() [/phpmanual/function.main.html]: Cannot assign to an array of nodes
  (duplicate subnodes or attr detected)
  必须给para指定索引告诉程序你要编辑哪个元素:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->chapter->para[1] = "Removed CDATA";
  •   print $book->chapter->asXML();
  输出:

  •   
  •   Acessing Elements
  •   Elements are accessed as properties
  •   Removed CDATA
  •   
  这样,第二个para元素的内容被改为Removed CDATA。如果要编辑一个在文档中唯一存在的元素可不必指定索引,直接修改。如修改title:

  •   $book = simplexml_load_file('sxml.xml');

  •   $book->chapter->title = "New>
  •   $book->chapter->para[1] = "Removed CDATA";
  •   print $book->chapter->asXML();
  输出:

  •   

  •   New>
  •   Elements are accessed as properties
  •   Removed CDATA
  •   

  强烈建议使用索引来编辑元素,除非你对文档的结果非常确定。使用索引来编辑title元素会比较安全,如$book->chapter->title[0] = “New>  编辑有子树的元素

  •   $book = simplexml_load_file('sxml.xml');
  •   $cholder = $book->bookinfo->copyright->holder;
  •   print $cholder->asXML()."/n";
  •   $book->bookinfo = "No Book Info";
  •   print $book->bookinfo->asXML()."/n";
  •   print $cholder->asXML()."/n";
  输出:

  •   Rob Richards
  •   No Book Info
  •   Warning: SimpleXMLElement::asXML() [/phpmanual/function.asXML.html]: Node no
  •   longer exists in N:/CVS Projects/php5/Debug_TS/booksxe.php on line 7
  这段代码中,首先将文档中的holder元素赋值给$cholder变量,然后打印该变量。bookinfo元素包含有title,author和 copyright子树,它的内容被字符串No Book Info代替,从bookinfo的输出结果可以看出,它的子树被清空并且被字符串代替了。接着试图再次打印$cholder变量的XML内容,程序输出一个警告,这个变量依然是一个SimpleXMLElement对象,但它所属的节点在bookinfo元素改变时已经被破坏了。
  另一种情况。将bookinfo元素中的子元素用字符串 代替。

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->bookinfo = "SimpleXML in PHP 5";
  •   print $book->bookinfo->asXML()."/n";
  如果你认为上述代码将bookinfo中的内容清空后再给bookinfo创建了一个子节点title,那么你错了。输出结果是
  SimpleXML in PHP 5
  实际上bookinfo元素的子元素都被移除了,但是新赋值的XML数据被转义成文本内容,而不是一个新的子元素。
  如果想用一个子树代替另一个子树,可以利用DOM扩展:

  •   $book = simplexml_load_file('sxml.xml');
  •   $bookinfo = dom_import_simplexml($book->bookinfo);
  •   /* 移除bookinfo元素下的所有子元素*/
  •   while ($bookinfo->firstChild) {
  •   $bookinfo->removeChild($bookinfo->firstChild);
  •   }
  •   $bookinfo->appendChild(new DOMElement("title", "SimpleXML in PHP 5"));
  •   print $book->bookinfo->asXML()."/n";
  输出结果:

  •   
  •   SimpleXML in PHP 5
  •   
  移除元素
  可以用PHP内置函数unset()来将一个元素从树中移除。unset()的参数必须是一个SimpleXMLElement,用属性方法来访问要移除的元素。例如,从chapter节点移除title元素:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->chapter->para[1] = "Removed CDATA";
  •   unset($book->chapter->title);
  •   print $book->chapter->asXML();
  上述代码执行后,chapter的结构为:

  •   

  •   Elements are accessed as properties
  •   Removed CDATA
  •   
  将这个结果与下面代码执行的结果想比较:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->chapter->para[1] = "Removed CDATA";
  •   $title = $book->chapter->title;
  •   unset($title);
  •   print $book->chapter->asXML();
  输出结果

  •   
  •   Acessing Elements
  •   Elements are accessed as properties
  •   Removed CDATA
  •   
  title元素没有被移除,unset函数只对$title变量作用并没有将title元素从树中移除。
  在移除一个元素时必须注意,用索引来指定的特定元素不会被移除:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->chapter->para[1] = "Removed CDATA";
  •   unset($book->chapter->title[0]);
  •   print $book->chapter->asXML();
  输出:

  •   
  •   Acessing Elements
  •   Elements are accessed as properties
  •   Removed CDATA
  •   
  如果要移除所有的para元素时可以利用下面代码:

  •   $book = simplexml_load_file('sxml.xml');
  •   unset($book->chapter->para);
  •   print $book->chapter->asXML();
  输出:

  •   
  •   Acessing Elements


  •   
  问题是如果你只想移除其中的一个para元素时要怎么办。这时可以再次用到DOM扩展:

  •   $book = simplexml_load_file('sxml.xml');
  •   $chapter = dom_import_simplexml($book->chapter);
  •   $node = $chapter->lastChild;
  •   while($node) {
  •   if ($node->nodeName == "para") {
  •   $chapter->removeChild($node);
  •   $node = NULL;
  •   break;
  •   }
  •   $node = $node->previousSibling;
  •   }
  •   print $book->chapter->asXML();
  输出:

  •   
  •   Acessing Elements
  •   Elements are accessed as properties

  •   
  所幸的是PHP5.2开始已经支持删除用索引指定的元素了:

  •   $book = simplexml_load_file('sxml.xml');
  •   unset($book->chapter->para[1]);
  •   print $book->chapter->asXML();
  访问属性
  读取属性
  下面的代码输出了book元素中的lang属性

  •   $book = simplexml_load_file('sxml.xml');
  •   print $book['lang'];
  访问用索引指定的元素的属性:

  •   $book = simplexml_load_file('sxml.xml');
  •   print $book->chapter[0]['id'];
  在不知道属性名的情况下可以用attributes()方法来输出属性:

  •   $book = simplexml_load_file('sxml.xml');
  •   foreach($book->chapter->attributes() AS $attribute) {
  •   print $attribute."/n";
  •   }
  如果要获得位置的属性名,可以使用DOM扩展:

  •   $book = simplexml_load_file('sxml.xml');
  •   foreach($book->chapter->attributes() AS $attribute) {
  •   $att = dom_import_simplexml($attribute);
  •   print $att->nodeName."/n";
  •   print $attribute."/n";
  •   }
  修改属性
  修改属性的值跟修改元素的值一样,直接对其赋值就可以了:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book['lang'] = "es";
  •   print $book['lang'];
  添加一个属性也很简单,如果对一个不存在的属性名进行赋值就给元素创建一个新属性

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->bookinfo->author->firstname["prefix"] = "Mr.";
  •   print $book->bookinfo->author->asXML();
  输出:

  •   
  •   Rob
  •   Richards
  •   
  移除属性
  移除属性也用到unset()函数:

  •   $book = simplexml_load_file('sxml.xml');
  •   $book->bookinfo->author->firstname["prefix"] = "Mr.";
  •   print $book->bookinfo->author->firstname->asXML()."/n/n";
  •   unset($book->bookinfo->author->firstname["prefix"]);
  •   print $book->bookinfo->author->firstname->asXML();
  输出:

  •   Rob

  •   Rob
  扩展SimpleXMLElement类

  •   class mySXE extends SimpleXMLElement {
  •   function appendChild($name, $content) {
  •   $dom = dom_import_simplexml($this);
  •   $dom->appendChild($dom->ownerDocument->createElement($name, $content));
  •   }
  •   }
  当实例化扩展的类时,文档的每个节点对象的类型都是扩展类的类型。

  •   $sxe = new mySXE("");
  •   $sxe->node1->appendChild("node2", "content");
  •   print $sxe->asXML();
  输出:

  •   
  •   content
  使用new方法可以用来处理字符串类型的XML,如果XML保存在一个文件中,那么可以将扩展的类名作为第二个参数传给simplexml_load_string或simplexml_load_file

  •   $sxe = simplexml_load_string("", "mySXE");
  •   $sxe->node1->appendChild("node2", "content");
  •   print $sxe->asXML();
  输出结果与用new关键字输出的结果一样。
  在SimpleXML中使用命名空间
  将清单7-1的内容改为

  •   
  •   
  •   
  •   SimpleXML in PHP 5
  •   
  •   Rob
  •   Richards
  •   
  •   
  •   2005
  •   Rob Richards
  •   
  •   
  •   
  如果试图用普通的方法来访问元素或属性,你会分析这并不可行,例如:

  •   $book = simplexml_load_file('sxmlns.xml');
  •   print $book["lang"]."/n";
  •   print $book->bookinfo->title."/n";
  输出的结果是两行空白。
  在访问命名空间节点前,必须使用children()和attributes()方法。这两个方法不仅可以在没有指定参数的时候使用,也可以在指定一个 URI命名空间作为参数使用。如果一个SimleXMLElement对象是从这两个方法返回的,那么你就可以像普通的元素和属性一样访问命名空间下的元素和属性:

  •   $book = simplexml_load_file('sxmlns.xml');
  •   /* 返回 http://www.example.com/ns2 命名空间下的所有属性 */
  •   $bookatts = $book->attributes("http://www.example.com/ns2");
  •   print $bookatts["lang"]."/n";
  •   /* 返回 http://www.example.com/ns1 命名空间下的所有元素*/
  •   $bookns = $book->children("http://www.example.com/ns1");
  •   $bookinfo = $bookns->bookinfo;
  •   /* 重置命名空间来访问非命名空间的元素 */
  •   $nonsbkinfo = $bookinfo->children();
  •   print $nonsbkinfo->title."/n";
  children()和attributes()方法可以被看做是过滤器,如果没有参数或者传递一个NULL作为参数,这两个方法将返回非命名空间下的元素或属性;否则将返回特定命名空间下的元素或属性。在重置之前,命名空间仍然起作用并且被子节点继承。例如,使用$bookinfo被设置为命名空间http://www.example.com/ns1的对象,可以使用 print $bookinfo->author->firstname来但因author中的firstname元素。所有的元素都在命名空间下,因此你在创建$bookinfo对象时不必一直使用children()设置命名空间。
  本文转载于http://blog.csdn.net/guoguo1980/article/details/2436318


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-653249-1-1.html 上篇帖子: PHP通过SimpleXML访问xml文档(一) 下篇帖子: PHP添加SOAP模块
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表