SimpleXML

介绍

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

使用SimpleXML

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

清单7-1 sml.xml

  1. "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">

  2.    

  3.         SimpleXML in PHP 5

  4.        

  5.             Rob

  6.             Richards

  7.        

  8.        

  9.             2005

  10.             Rob Richards

  11.        

  12.    

  13.    

  14.         Using SimpleXML

  15.         An example DOM Tree using DocBook.

  16.    

  17.    

  18.         Accessing Elements

  19.         Elements are accessed as properties

  20.        

  21.        

  22.        

  23.         $data = '

  24.         content';

  25.         $sxe = simplexml_load_string($data);

  26.         var_dump($sxe);

  27.         ?>

  28.         ]]>

  29.        

  30.    

创建一个SimpleXMLElement对象

使用new关键字创建

  1. $xml = "Content";

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

使用simplexml_load_string()创建

  1. $xml = "Content";

  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 = "content";

  2. $sxe = new SimpleXMLElement($xml);

  3. print $sxe->asXML();

  4. $sxe->asXML('test.xml');

输出:

  1. content

访问元素节点

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

访问元素

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

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

  2. /* Access the bookinfo child element of the book element */

  3. $bookinfo = $book->bookinfo;

  4. /* Access the title child element from the bookinfo element */

  5. $title = $bookinfo->title;

  6. ?>

如果使用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. $book = simplexml_load_file('sxml.xml');

  2. $bookinfo = $book->bookinfo;

  3. $title = $bookinfo->title;

  4. /* Object examined with var_dump */

  5. var_dump($title);

  6. /* Using print with element containing text-only content */

  7. print "Title: ".$title."/n";

  8. $author = $bookinfo->author;

  9. /* Object examined with var_dump */

  10. var_dump($author);

  11. /* Using print with element containing child elements */

  12. print "Author: ".$author."/n";

  13. ?>

这段代码检查了两个SimpleXMLElement对象,$author和$title。两者的区别是$author元素有包含子元素而$title元素只包含一个文本节点。
输出如下:
object(SimpleXMLElement)#4 (1) {
[0]=>
string(18) “SimpleXML in PHP 5″
}
Title: SimpleXML in PHP 5
object(SimpleXMLElement)#6 (2) {
[”firstname”]=>
string(3) “Rob”
[”surname”]=>
string(8) “Richards”
}
Author:

检查输出结果可以发现,$title是一个包含有文本内容的SimpleXMLElement对象,索引0表示元素的文本内容,当打印$title时,文本内容将以字符串形式返回。

$author元素有两个子元素,从输出结果可以看出,这些子元素被看成SimpleXMLElement对象的属性,这些属性的值是它们对应的节点包含的内容。用print输出$author时,输出结果是空格和换行符。

如果一个元素无子元素,只包含文本内容,那么可以将此元素所对应的SimpleXMLElement对象视为一个字符串来使用,有些情况下,为了获得以字符串形式返回文本内容,必须执行类型转换操作:

  1. $titlecontent = (string) $title;

有 子元素的元素所对应的SimpleXMLElement对象将返回该对象直属的文本节点,而不是任一子元素的内容。如果用print输出$author, 将得到一个27字符长度,包含空格和换行符的字符。 Neither of the child elements,firstname or surname, nor their content is returned in the string.

为了理解最后一点,可以运行一些下面这段代码:

  1. $doc = new SimpleXMLElement('somesubtextthing');

  2. print $doc;

使用迭代对象

SimpleXMLElement 对象在大多数情况下是可迭代的,可以用这个特性来访问文档中多个元素名一样的节点,如清单7-1中的para元素。在使用元素名作为属性来访问一个元素 时,SimpleXMLElement对象不是一个单一节点的存取器,它实际上是作为属性访问的元素名节点的集合。直接利用元素名作为属性访问实际上访问 访问这个集合中的第一个元素。

看下这段代码

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

  2. $para = $book->chapter->para;

  3. print $para."/n";

  4. foreach($para AS $node) {

  5.     print $node."/n";

  6. }

这 段代码中,$para变量就是para元素的集合,实际上包含了两个元素。如果直接访问$para的话实际上是访问第一个para元素,利用迭代可以看出 $para所包含的内容是两个元素。其中CDATA节点被看做是纯文本的内容,其中包含的空格和换行符都会被如实输出。

用迭代的方式来访问所有的元素显然不太实际,有时候我们希望访问结果集中的某个特定的元素,这时可以使用从0开始的索引来访问这个结果集,例如:

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

  2. $para = $book->chapter->para[1];

  3. print "Content: ".$para."/n";

  4. foreach($para AS $node) {

  5.     print "Iter Content: ".$node."/n";

  6. }

运行这段代码会发现foreach循环失效了,这是因为SimpleXML知道你只是在寻找结果集中某个特定的元素,这种情况下对象是不可迭代的。

Caution:使用索引方式访问一个SimpleXMLElement对象会返回一个不可以迭代的对象,因为它是一个单一的元素而不是一个元素集。

访问未知元素

在不知道XML文档的结构的情况下可以利用SimpleXML中的children()方法来返回一个可以迭代方式访问的某个元素的所有子元素的SimpleXML对象。如:

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

  2. $author = $book->bookinfo->author;

  3. $children = $author->children();

  4. foreach($children AS $child) {

  5.     print $child."/n";

  6. }

上述代码用children()方法返回了author节点下的所有子元素,然后用foreach循环输出。也可以使用索引方式访问返回的子元素,如echo $children[1];。

理解PHP对象函数

SimpleXMLElement对象的属性是动态的,因为这些属性是由对象实例决定的,而不是由类本身决定的。在PHP中,可以利用get_object_vars()函数来返回某个对象的所有属性,返回的结果是一个包含属性和值的数组,如:

  1. $props = get_object_vars($author);

  2. foreach ($props AS $name=>$value) {

  3.     print $name.": ".$value."/n";

  4. }

输出:
firstname: Rob
surname: Richards
这段代码访问的子元素都只包含文本内容,所以返回的数组只包含属性名和值,对于一个包含许多子节点的元素,返回的结果稍微复杂点:

  1. $props = get_object_vars($book->bookinfo);

  2. var_dump($props);

输出:

array(3) {
[”title”]=>
string(18) “SimpleXML in PHP 5″
[”author”]=>
object(SimpleXMLElement)#4 (2) {
[”firstname”]=>
string(3) “Rob”
[”surname”]=>
string(8) “Richards”
}
[”copyright”]=>
object(SimpleXMLElement)#5 (2) {
[”year”]=>
string(4) “2005″
[”holder”]=>
string(12) “Rob Richards”
}
}

使用DOM互操作

另一种访问未知元素的方法是使用DOM,可以将一个节点导入DOM扩展,然后使用DOM的属性和方法来处理。

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

  2. $author = $book->bookinfo->author;

  3. $children = $author->children();

  4. foreach($children AS $child) {

  5.     /* Import node into DOM, and get nodeName */

  6.     $element = dom_import_simplexml($child);

  7.     $name = $element->nodeName;

  8.     print $name.": ".$child."/n";

  9. }

将节点导入DOM扩展时并没有创建一个节点的副本(copy),而是直接访问导入的节点(JIMMY注:这个概念很重要)。


本文转载于http://blog.csdn.net/guoguo1980/article/details/2436318