家园首页 Php4手册 我的相册 家园下载 个人文集 给我留言
我形我塑,网络相册,www.5x54.com 相册 相册 心情相册,少女相册 免费申请,我形我塑免费相册
 家园 个人文集   http://www.5x54.com
 


用 PHP 读取和编写 XML DOM


作者:ibm.com    点击: 读取中...

2006 年 2 月 06 日 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
有许多技术可用于用 PHP 读取和编写 XML。本文提供了三种方法读取 XML:使用 DOM 库、使用 SAX 解析器和使用正则表达式。还介绍了使用 DOM 和 PHP 文本模板编写 XML。 (%$$204#^67)心情家园www.bbsdiy.net
用 PHP 读取和编写可扩展标记语言(XML)看起来可能有点恐怖。实际上(%$$204#^67)心情家园www.bbsdiy.net,XML 和它的所有相关技术可能是恐怖的(%$$204#^67)心情家园www.bbsdiy.net,但是用 PHP 读取和编写 XML 不一定是项恐怖的任务。首先(%$$204#^67)心情家园www.bbsdiy.net,需要学习一点关于 XML 的知识 —— 它是什么(%$$204#^67)心情家园www.bbsdiy.net,用它做什么。然后(%$$204#^67)心情家园www.bbsdiy.net,需要学习如何用 PHP 读取和编写 XML(%$$204#^67)心情家园www.bbsdiy.net,而有许多种方式可以做这件事。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
本文提供了 XML 的简短入门(%$$204#^67)心情家园www.bbsdiy.net,然后解释如何用 PHP 读取和编写 XML。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
什么是 XML? (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
XML 是一种数据存储格式。它没有定义保存什么数据(%$$204#^67)心情家园www.bbsdiy.net,也没有定义数据的格式。XML 只是定义了标记和这些标记的属性。格式良好的 XML 标记看起来像这样: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<name>Jack Herrington</name> (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
这个 <name> 标记包含一些文本:Jack Herrington。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
不包含文本的 XML 标记看起来像这样: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<powerUp /> (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
用 XML 对某件事进行编写的方式不止一种。例如(%$$204#^67)心情家园www.bbsdiy.net,这个标记形成的输出与前一个标记相同: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<powerUp></powerUp> (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
也可以向 XML 标记添加属性。例如(%$$204#^67)心情家园www.bbsdiy.net,这个 <name> 标记包含 first 和 last 属性: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<name first="Jack" last="Herrington" /> (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
也可以用 XML 对特殊字符进行编码。例如(%$$204#^67)心情家园www.bbsdiy.net,& 符号可以像这样编码: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
& (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
包含标记和属性的 XML 文件如果像示例一样格式化(%$$204#^67)心情家园www.bbsdiy.net,就是格式良好的(%$$204#^67)心情家园www.bbsdiy.net,这意味着标记是对称的(%$$204#^67)心情家园www.bbsdiy.net,字符的编码正确。清单 1 是一份格式良好的 XML 的示例。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 1. XML 图书列表示例 (%$$204#^67)心情家园www.bbsdiy.net
引用代码: (%$$204#^67)心情家园www.bbsdiy.net
 <books> (%$$204#^67)心情家园www.bbsdiy.net
 <book> (%$$204#^67)心情家园www.bbsdiy.net
 <author>Jack Herrington</author> (%$$204#^67)心情家园www.bbsdiy.net
 <title>PHP Hacks</title> (%$$204#^67)心情家园www.bbsdiy.net
 <publisher>O'Reilly</publisher> (%$$204#^67)心情家园www.bbsdiy.net
 </book> (%$$204#^67)心情家园www.bbsdiy.net
 <book> (%$$204#^67)心情家园www.bbsdiy.net
 <author>Jack Herrington</author> (%$$204#^67)心情家园www.bbsdiy.net
 <title>Podcasting Hacks</title> (%$$204#^67)心情家园www.bbsdiy.net
 <publisher>O'Reilly</publisher> (%$$204#^67)心情家园www.bbsdiy.net
 </book> (%$$204#^67)心情家园www.bbsdiy.net
 </books> (%$$204#^67)心情家园www.bbsdiy.net
 
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 1 中的 XML 包含一个图书列表。父标记 <books> 包含一组 <book> 标记(%$$204#^67)心情家园www.bbsdiy.net,每个 <book> 标记又包含 <author>、<title> 和 <publisher> 标记。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
当 XML 文档的标记结构和内容得到外部模式文件的验证后(%$$204#^67)心情家园www.bbsdiy.net,XML 文档就是正确的。模式文件可以用不同的格式指定。对于本文来说(%$$204#^67)心情家园www.bbsdiy.net,所需要的只是格式良好的 XML。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
如果觉得 XML 看起来很像超文本标记语言(HTML)(%$$204#^67)心情家园www.bbsdiy.net,那么就对了。XML 和 HTML 都是基于标记的语言(%$$204#^67)心情家园www.bbsdiy.net,它们有许多相似之处。但是(%$$204#^67)心情家园www.bbsdiy.net,要着重指出的是:虽然 XML 文档可能是格式良好的 HTML(%$$204#^67)心情家园www.bbsdiy.net,但不是所有的 HTML 文档都是格式良好的 XML。换行标记(br)是 XML 和 HTML 之间区别的一个好例子。这个换行标记是格式良好的 HTML(%$$204#^67)心情家园www.bbsdiy.net,但不是格式良好的 XML: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<p>This is a paragraph<br> (%$$204#^67)心情家园www.bbsdiy.net
With a line break</p>  (%$$204#^67)心情家园www.bbsdiy.net
这个换行标记是格式良好的 XML 和 HTML: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
<p>This is a paragraph<br /> (%$$204#^67)心情家园www.bbsdiy.net
With a line break</p>  (%$$204#^67)心情家园www.bbsdiy.net
如果要把 HTML 编写成同样是格式良好的 XML(%$$204#^67)心情家园www.bbsdiy.net,请遵循 W3C 委员会的可扩展超文本标记语言(XHTML)标准(参见 参考资料)。所有现代的浏览器都能呈现 XHTML。而且(%$$204#^67)心情家园www.bbsdiy.net,还可以用 XML 工具读取 XHTML 并找出文档中的数据(%$$204#^67)心情家园www.bbsdiy.net,这比解析 HTML 容易得多。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
使用 DOM 库读取 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
读取格式良好的 XML 文件最容易的方式是使用编译成某些 PHP 安装的文档对象模型 (DOM)库。DOM 库把整个 XML 文档读入内存(%$$204#^67)心情家园www.bbsdiy.net,并用节点树表示它(%$$204#^67)心情家园www.bbsdiy.net,如图 1 所示。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
图 1. 图书 XML 的 XML DOM 树 (%$$204#^67)心情家园www.bbsdiy.net
  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
树顶部的 books 节点有两个 book 子标记。在每本书中(%$$204#^67)心情家园www.bbsdiy.net,有 author、publisher 和 title 几个节点。author、publisher 和 title 节点分别有包含文本的文本子节点。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
读取图书 XML 文件并用 DOM 显示内容的代码如清单 2 所示。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 2. 用 DOM 读取图书 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: <?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";
  }
  
?>
   (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
脚本首先创建一个 new DOMdocument 对象(%$$204#^67)心情家园www.bbsdiy.net,用 load 方法把图书 XML 装入这个对象。之后(%$$204#^67)心情家园www.bbsdiy.net,脚本用 getElementsByName 方法得到指定名称下的所有元素的列表。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
在 book 节点的循环中(%$$204#^67)心情家园www.bbsdiy.net,脚本用 getElementsByName 方法获得 author、publisher 和 title 标记的 nodeValue。nodeValue 是节点中的文本。脚本然后显示这些值。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
可以在命令行上像这样运行 PHP 脚本: (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
% php e1.php  (%$$204#^67)心情家园www.bbsdiy.net
PHP Hacks - Jack Herrington - O'Reilly (%$$204#^67)心情家园www.bbsdiy.net
Podcasting Hacks - Jack Herrington - O'Reilly (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
可以看到(%$$204#^67)心情家园www.bbsdiy.net,每个图书块输出一行。这是一个良好的开始。但是(%$$204#^67)心情家园www.bbsdiy.net,如果不能访问 XML DOM 库该怎么办? (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
用 SAX 解析器读取 XML  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
读取 XML 的另一种方法是使用 XML Simple API(SAX)解析器。PHP 的大多数安装都包含 SAX 解析器。SAX 解析器运行在回调模型上。每次打开或关闭一个标记时(%$$204#^67)心情家园www.bbsdiy.net,或者每次解析器看到文本时(%$$204#^67)心情家园www.bbsdiy.net,就用节点或文本的信息回调用户定义的函数。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
SAX 解析器的优点是(%$$204#^67)心情家园www.bbsdiy.net,它是真正轻量级的。解析器不会在内存中长期保持内容(%$$204#^67)心情家园www.bbsdiy.net,所以可以用于非常巨大的文件。缺点是编写 SAX 解析器回调是件非常麻烦的事。清单 3 显示了使用 SAX 读取图书 XML 文件并显示内容的代码。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 3. 用 SAX 解析器读取图书 XML  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: <?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";
  }
  
?>
   (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
脚本首先设置 g_books 数组(%$$204#^67)心情家园www.bbsdiy.net,它在内存中容纳所有图书和图书信息(%$$204#^67)心情家园www.bbsdiy.net,g_elem 变量保存脚本目前正在处理的标记的名称。然后脚本定义回调函数。在这个示例中(%$$204#^67)心情家园www.bbsdiy.net,回调函数是 startElement、endElement 和 textData。在打开和关闭标记的时候(%$$204#^67)心情家园www.bbsdiy.net,分别调用 startElement 和 endElement 函数。在开始和结束标记之间的文本上面(%$$204#^67)心情家园www.bbsdiy.net,调用 textData。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
在这个示例中(%$$204#^67)心情家园www.bbsdiy.net,startElement 标记查找 book 标记(%$$204#^67)心情家园www.bbsdiy.net,在 book 数组中开始一个新元素。然后(%$$204#^67)心情家园www.bbsdiy.net,textData 函数查看当前元素(%$$204#^67)心情家园www.bbsdiy.net,看它是不是 publisher、title 或 author 标记。如果是(%$$204#^67)心情家园www.bbsdiy.net,函数就把当前文本放入当前图书。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
为了让解析继续(%$$204#^67)心情家园www.bbsdiy.net,脚本用 xml_parser_create 函数创建解析器。然后(%$$204#^67)心情家园www.bbsdiy.net,设置回调句柄。之后(%$$204#^67)心情家园www.bbsdiy.net,脚本读取文件并把文件的大块内容发送到解析器。在文件读取之后(%$$204#^67)心情家园www.bbsdiy.net,xml_parser_free 函数删除解析器。脚本的末尾输出 g_books 数组的内容。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
可以看到(%$$204#^67)心情家园www.bbsdiy.net,这比编写 DOM 的同样功能要困难得多。如果没有 DOM 库也没有 SAX 库该怎么办?还有替代方案么? (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
用正则表达式解析 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
可以肯定(%$$204#^67)心情家园www.bbsdiy.net,即使提到这个方法(%$$204#^67)心情家园www.bbsdiy.net,有些工程师也会批评我(%$$204#^67)心情家园www.bbsdiy.net,但是确实可以用正则表达式解析 XML。清单 4 显示了使用 preg_ 函数读取图书文件的示例。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 4. 用正则表达式读取 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: <?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"  );
  }
  
?>
  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
请注意这个代码有多短。开始时(%$$204#^67)心情家园www.bbsdiy.net,它把文件读进一个大的字符串。然后用一个 regex 函数读取每个图书项目。最后用 foreach 循环(%$$204#^67)心情家园www.bbsdiy.net,在每个图书块间循环(%$$204#^67)心情家园www.bbsdiy.net,并提取出 author、title 和 publisher。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
那么(%$$204#^67)心情家园www.bbsdiy.net,缺陷在哪呢?使用正则表达式代码读取 XML 的问题是(%$$204#^67)心情家园www.bbsdiy.net,它并没先进行检查(%$$204#^67)心情家园www.bbsdiy.net,确保 XML 的格式良好。这意味着在读取之前(%$$204#^67)心情家园www.bbsdiy.net,无法知道 XML 是否格式良好。而且(%$$204#^67)心情家园www.bbsdiy.net,有些格式正确的 XML 可能与正则表达式不匹配(%$$204#^67)心情家园www.bbsdiy.net,所以日后必须修改它们。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
我从不建议使用正则表达式读取 XML(%$$204#^67)心情家园www.bbsdiy.net,但是有时它是兼容性最好的方式(%$$204#^67)心情家园www.bbsdiy.net,因为正则表达式函数总是可用的。不要用正则表达式读取直接来自用户的 XML(%$$204#^67)心情家园www.bbsdiy.net,因为无法控制这类 XML 的格式或结构。应当一直用 DOM 库或 SAX 解析器读取来自用户的 XML。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
用 DOM 编写 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
读取 XML 只是公式的一部分。该怎样编写 XML 呢?编写 XML 最好的方式就是用 DOM。清单 5 显示了 DOM 构建图书 XML 文件的方式。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 5. 用 DOM 编写图书 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: <?php
  $books  
=  array();
  
$books  []  =  array(
  
'title'  =>  'PHP  Hacks',
  
'author'  =>  'Jack  Herrington',
  
'publisher'  =>  "O'Reilly"
  
);
  
$books  []  =  array(
  
'title'  =>  'Podcasting  Hacks',
  
'author'  =>  'Jack  Herrington',
  
'publisher'  =>  "O'Reilly"
  
);
  
  
$doc  =  new  DOMDocument();
  
$doc->formatOutput  =  true;
  
  
$r  =  $doc->createElement(  "books"  );
  
$doc->appendChild(  $r  );
  
  foreach(  
$books  as  $book  )
  {
  
$b  =  $doc->createElement(  "book"  );
  
  
$author  =  $doc->createElement(  "author"  );
  
$author->appendChild(
  
$doc->createTextNode(  $book['author']  )
  );
  
$b->appendChild(  $author  );
  
  
$title  =  $doc->createElement(  "title"  );
  
$title->appendChild(
  
$doc->createTextNode(  $book['title']  )
  );
  
$b->appendChild(  $title  );
  
  
$publisher  =  $doc->createElement(  "publisher"  );
  
$publisher->appendChild(
  
$doc->createTextNode(  $book['publisher']  )
  );
  
$b->appendChild(  $publisher  );
  
  
$r->appendChild(  $b  );
  }
  
  echo  
$doc->saveXML();
  
?>
  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
在脚本的顶部(%$$204#^67)心情家园www.bbsdiy.net,用一些示例图书装入了 books 数组。这个数据可以来自用户也可以来自数据库。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
示例图书装入之后(%$$204#^67)心情家园www.bbsdiy.net,脚本创建一个 new DOMDocument(%$$204#^67)心情家园www.bbsdiy.net,并把根节点 books 添加到它。然后脚本为每本书的 author、title 和 publisher 创建节点(%$$204#^67)心情家园www.bbsdiy.net,并为每个节点添加文本节点。每个 book 节点的最后一步是重新把它添加到根节点 books。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
脚本的末尾用 saveXML 方法把 XML 输出到控制台。(也可以用 save 方法创建一个 XML 文件。)脚本的输出如清单 6 所示。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 6. DOM 构建脚本的输出 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: % php e4.php  (%$$204#^67)心情家园www.bbsdiy.net
 <?xml version="1.0"?> (%$$204#^67)心情家园www.bbsdiy.net
 <books> (%$$204#^67)心情家园www.bbsdiy.net
 <book> (%$$204#^67)心情家园www.bbsdiy.net
 <author>Jack Herrington</author> (%$$204#^67)心情家园www.bbsdiy.net
 <title>PHP Hacks</title> (%$$204#^67)心情家园www.bbsdiy.net
 <publisher>O'Reilly</publisher> (%$$204#^67)心情家园www.bbsdiy.net
 </book> (%$$204#^67)心情家园www.bbsdiy.net
 <book> (%$$204#^67)心情家园www.bbsdiy.net
 <author>Jack Herrington</author> (%$$204#^67)心情家园www.bbsdiy.net
 <title>Podcasting Hacks</title> (%$$204#^67)心情家园www.bbsdiy.net
 <publisher>O'Reilly</publisher> (%$$204#^67)心情家园www.bbsdiy.net
 </book> (%$$204#^67)心情家园www.bbsdiy.net
 </books> (%$$204#^67)心情家园www.bbsdiy.net
 % (%$$204#^67)心情家园www.bbsdiy.net
  (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
使用 DOM 的真正价值在于它创建的 XML 总是格式正确的。但是如果不能用 DOM 创建 XML 时该怎么办? (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
用 PHP 编写 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
如果 DOM 不可用(%$$204#^67)心情家园www.bbsdiy.net,可以用 PHP 的文本模板编写 XML。清单 7 显示了 PHP 如何构建图书 XML 文件。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 7. 用 PHP 编写图书 XML (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
引用代码: <?php
  $books  
=  array();
  
$books  []  =  array(
  
'title'  =>  'PHP  Hacks',
  
'author'  =>  'Jack  Herrington',
  
'publisher'  =>  "O'Reilly"
  
);
  
$books  []  =  array(
  
'title'  =>  'Podcasting  Hacks',
  
'author'  =>  'Jack  Herrington',
  
'publisher'  =>  "O'Reilly"
  
);
  
?>
  <books>
  <?php
  
  
foreach(  $books  as  $book  )
  {
  
?>
  <book>
  <title><?php  echo(  $book['title']  );  ?></title>
  <author><?php  echo(  $book['author']  );  ?>
  </author>
  <publisher><?php  echo(  $book['publisher']  );  ?>
  </publisher>
  </book>
  <?php
  
}
  
?>
  </books>
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
脚本的顶部与 DOM 脚本类似。脚本的底部打开 books 标记(%$$204#^67)心情家园www.bbsdiy.net,然后在每个图书中迭代(%$$204#^67)心情家园www.bbsdiy.net,创建 book 标记和所有的内部 title、author 和 publisher 标记。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
这种方法的问题是对实体进行编码。为了确保实体编码正确(%$$204#^67)心情家园www.bbsdiy.net,必须在每个项目上调用 htmlentities 函数(%$$204#^67)心情家园www.bbsdiy.net,如清单 8 所示。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
清单 8. 使用 htmlentities 函数对实体编码 (%$$204#^67)心情家园www.bbsdiy.net
  (%$$204#^67)心情家园www.bbsdiy.net
引用代码: <books>
  <?
php
  
  
foreach(  $books  as  $book  )
  {
  
$title  =  htmlentities(  $book['title'],  ENT_QUOTES  );
  
$author  =  htmlentities(  $book['author'],  ENT_QUOTES  );
  
$publisher  =  htmlentities(  $book['publisher'],  ENT_QUOTES  );
  
?>
  <book>
  <title><?php  echo(  $title  );  ?></title>
  <author><?php  echo(  $author  );  ?>  </author>
  <publisher><?php  echo(  $publisher  );  ?>
  </publisher>
  </book>
  <?php
  
}
  
?>
  </books>
(%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
这就是用基本的 PHP 编写 XML 的烦人之处。您以为自己创建了完美的 XML(%$$204#^67)心情家园www.bbsdiy.net,但是在试图使用数据的时候(%$$204#^67)心情家园www.bbsdiy.net,马上就会发现某些元素的编码不正确。 (%$$204#^67)心情家园www.bbsdiy.net
(%$$204#^67)心情家园www.bbsdiy.net
转自:http://www.ibm.com/developerworks/cn/opensource/os-xmldomphp/

收藏此文章     打印  更新     编辑此文章    『关闭窗口』