面向 PHP 开发人员的 XML,第 3 部分: 读、操纵和写
时间:2008-02-20 来源:liuxingyuyuni
2007 年 4 月 29 日
本系列包括三部分,这是最后一部分,进一步讨论在 PHP5 中读、操纵和写 XML 的技术。本文将重点讨论在更复杂的环境中使用我们已经熟悉的 API 如 DOM 和 SimpleXML,并将第一次接触 XSL 扩展。
简介
PHP5 为开发人员提供了更多处理 XML 的工具。新增的和修改的扩展如 DOM、SimpleXML 和 XSL 大大压缩了处理 XML 需要编写的代码。PHP5 中的 DOM 符合 W3C 标准。最重要的是,这些扩展之间具有很强的互操作性,因而提供了更多的功能,比如通过交换格式来扩展可用性、W3C XPath、以及更多全面的功能。这里您将看到输入和输出选项,依赖 Yahoo Web Service REST 协议接口为现已熟知的 DOM 和 SimpleXML 扩展提供更复杂的展示,最后还将讨论 XSL 扩展。
回页首
内容回顾
本系列的第一篇文章介绍了 XML 的基本知识。主要介绍简单的入门级应用程序编程接口(API),举例说明了对于简单、可预测和较小的 XML 文档,SimpleXML(有时需要与文档对象模型(DOM)结合使用)是一种理想的技术。第 2 部分横向介绍了 PHP5 中所提供的解析 XML 的 API,包括 SimpleXML、DOM、Simple API for XML (SAX) 和 XMLReader,讨论了针对不同大小和复杂度的 XML 文档使用何种解析技术最为适当。
PHP5 中的 XML
可扩展标记语言(XML)不仅仅是一种标记语言,还是一种基于文本的数据存储格式,提供了应用和描述信息的树状结构的一种基于文本的方法。下面我们将看到 Web 服务上下文中的 XML,也许这是在企业之外推动 XML 迅速壮大的最重要的因素之一。
PHP5 提供了全新的和全部改写的 XML 操作扩展,都以相同的 libxml2 代码为基础。这一公共基础为这些扩展提供了互操作性,扩展了各自的功能。基于树的解析器包括 SimpleXML、DOM 和 XSLT 处理程序。如果熟悉其他语言中的 DOM,则使用 PHP 实现类似的功能会更简单。基于流的解析器包括 Simple API for XML (SAX) 和 XMLReader。SAX 的功能与 PHP4 中一样。
回页首
使用 DOM 操纵 XML
DOM 可用于操纵 XML 文件。只有在 XML 文件比较小的情况下使用 DOM 才有效。使用这种方法的优点在于众所周知的 W3C DOM 是一种坚实的标准,它具有丰富的方法和编程的灵活性。DOM 的缺点在于编码比较困难和处理大型文档时存在性能问题。
回页首
使用 DOM
使用 DOM 可以构建、修改、查询、验证和转换 XML 文档。所有 DOM 方法和属性都能使用,大部分 DOM level 2 方法都有适当的属性支持。由于非凡的灵活性,可以使用 DOM 解析任意复杂的文档。但是要记住,如果一次将整个大型 XML 文档载入内存,则取得灵活性的代价相当高昂。
本文中的例子使用 Yahoo 搜索 API、PHP5 和 REpresentational State Transfer (REST) 来说明 DOM 在一种有趣的应用程序环境中的使用。Yahoo 选择 REST 是因为多数开发人员认为 REST 以使用 SOAP 的 20% 的代价提供了其 80% 的价值。选择这个应用程序来说明 PHP/XML 是因为 Web 服务的盛行可能是推动 XML 在企业之外迅速增长的最重要因素之一。
REST 通常从服务入口 URL 开始形成一次请求,然后以查询字符串的形式追加搜索参数。
清单 1
使用 DOM 扩展解析查询的结果。
清单 1. 使用 DOM 的 Yahoo 示例代码
firstChild;
//Next, loop through each of its attributes
foreach($root->attributes as $attr) {
$res[$attr->name] = $attr->value;
}
//Now, loop through each of the children of the root element
//and treat each appropriately.
//Start with the first child node. (The counter, i, is for
//tracking results.
$node = $root->firstChild;
$i = 0;
//Now keep looping through as long as there is a node to work
//with. (At the bottom of the loop, the code moves to the next
//sibling, so when it runs out of siblings, the routine stops.
while($node) {
//For each node, check to see whether it's a Result element or
//one of the informational elements at the start of the document.
switch($node->nodeName) {
//Result elements need more analysis.
case 'Result':
//Add each child node of the Result to the result object,
//again starting with the first child.
$subnode = $node->firstChild;
while($subnode) {
//Some of these nodes just are just whitespace, which does
//not have children.
if ($subnode->hasChildNodes()){
//If it does have children, get a NodeList of them, and
//loop through it.
$subnodes = $subnode->childNodes;
foreach($subnodes as $n) {
//Again check for children, adding them directly or
//indirectly as appropriate.
if($n->hasChildNodes()) {
foreach($n->childNodes as $cn){
$res[$i][$subnode->nodeName][$n->nodeName]=
trim($cn->nodeValue);
}
} else {
$res[$i][$subnode->nodeName]=trim($n->nodeValue);
}
}
}
//Move on to the next subnode.
$subnode = $subnode->nextSibling;
}
$i++;
break;
//Other elements are just added to the result object.
default:
$res[$node->nodeName] = trim($node->nodeValue);
break;
}
//Move on to the next Result of informational element
$node = $node->nextSibling;
}
return $res;
}
//First, convert the XML to a DOM object you can manipulate.
$res = xml_to_result($dom);
//Use one of those "informational" elements to display the total
//number of results for the query.
echo "The query returns ".$res["totalResultsAvailable"].
" total results The first 10 are as follows:";
//Now loop through each of the actual results.
for($i=0; $i".
$res[$i]['Title'].": ";
echo $res[$i]['Summary'];
echo "
";
}
?>
回页首
使用 SimpleXML 操纵 XML
SimpleXML 扩展适合于操纵不很复杂或者嵌套不太深并且没有混合内容的 XML 文档。SimpleXML 比 DOM 更容易编码,就像名称所暗示的那样。如果处理的文档结构已知,就更加直观。libXML2 架构的互操作性大大增强了 DOM 和 SimpleXML 的灵活性,能够随意在 DOM 和 SimpleXML 之间交换导入格式。
使用 SimpleXML
使用 SimpleXML 操纵文档非常简单,编码也很快捷。下面的代码使用 SimpleXML 扩展解析查询结果。如您所料,下面的 SimpleXML 代码(参见
清单 2
)比上面
清单 1
所示的 DOM 代码示例更紧凑。
清单 2. Yahoo SimpleXML 例子
attributes() as $name=>$attr) {
$res[$name]=$attr;
}
//Use one of those "informational" elements to display the total
//number of results for the query.
echo "The query returns ".$res["totalResultsAvailable"].
" total results The first 10 are as follows:";
//Unlike with DOM, where we loaded the entire document into the
//result object, with SimpleXML, we get back an object in the
//first place, so we can just use the number of results returned
//to loop through the Result members.
for($i=0; $iResult[$i];
echo "ClickUrl."'>".
$thisResult->Title.": ";
echo $thisResult->Summary;
echo "
";
}
?>
清单 3
在
清单 2
所示 SimpleXML 例子的基础上增加了缓存层。任何查询结果都能缓存两个小时。
清单 3. 带有缓存层的 Yahoo SimpleXML 例子
(time()-7200)) {
//If there's a valid cache file, load its data.
$data = file_get_contents($cache);
} else {
//If there's no valid cache file, grab a live version of the
//data and save it to a temporary file. Once the file is complete,
//copy it to a permanent file. (This prevents concurrency issues.)
$data = file_get_contents($query);
$tempName = tempnam('c:\temp','YWS');
file_put_contents($tempName, $data);
rename($tempName, $cache);
}
//Wherever the data came from, load it into a SimpleXML object.
$xml = simplexml_load_string($data);
//From here, the rest of the file is the same.
// Load up the root element attributes
foreach($xml->attributes() as $name=>$attr) {
$res[$name]=$attr;
}
...
回页首
使用 XSL 操纵 XML
可扩展样式表语言(XSL)是一种用于操纵 XML 文档的功能性 XML 语言。根据样式表定义(类似于 CSS 实现规则的方式),使用 XSL 可以将 XML 文档转换成重新定义的 XML 文档、XHTML 文档、HTML 文档或者文本文档。PHP5 的 W3C 标准实现支持与 DOM 和 XPath 之间的互操作。可扩展样式表语言转换(XSLT)是一种基于 libxml2 的 XML 扩展,它的样式表也是 XML 文档。XSLT 将 XML 源树转换成 XML 或者 XML 类型的结果树。这些转换将样式表中指定的一系列规则应用于 XML 数据。XSLT 可以向输出文件中添加或者从其中删除元素或属性。允许开发人员排序或者重新排列元素,决定隐藏或者显示某些元素。不同的样式表可让 XML 提供不同媒介的适当显示,比如屏幕显示和打印显示。XSLT 使用 XPath 在原始 XML 文档中导航。XSLT 转换模型通常涉及到一个 XML 源文件、包含一个或多个处理模板的 XSLT 文件以及一个 XSLT 处理程序。XSLT 文档必须使用 DOM 加载。PHP5 仅支持 libxslt 处理程序。
使用 XSL
XSL 一个有趣的应用是动态地创建 XML 文件以便包含刚从数据库中选择的数据。利用这种技术可以创建完整的 Web 应用程序,在其中用数据库查询得到的 XML 文件编写 PHP 脚本,然后使用 XSL 转换生成真正的 HTML 文档。
这种方法将表示层和业务层彻底分开,从而能够独立地维护这些层。
清单 4
演示了 XML 输入文件、XSL 样式表、XSLT 处理程序和多种可能的输出之间的关系。
清单 4. XML 转换
load('recipe.xsl');
// Load the stylesheet into the processor
$xslt->importStylesheet($xsl);
// Load XML input file
$xml = new DOMDocument();
$xml->load('recipe.xml');
//Now choose an output method and transform to it:
// Transform to a string
$results = $xslt->transformToXML($xml);
echo "String version:";
echo htmlentities($results);
// Transform to DOM object
$results = $xslt->transformToDoc($xml);
echo "The root of the DOM Document is ";
echo $results->documentElement->nodeName;
// Transform to a file
$results = $xslt->transformToURI($xml, 'results.txt');
?>
回页首
结束语
本系列的第一部分讨论了使用文档对象模型和 SimpleXML 执行简单和复杂的解析任务。第 2 部分考察了 XMLReader 的使用,它提供了一种比 SAX 更快更简单的办法。
这篇文章又介绍了如何访问基于 REST 的 Web 服务这类远程文件,如何使用 XSLT 轻松地将 XML 数据输出到字符串、DOM 文档对象或者文件。
参考资料
学习
- 您可以参阅本文在 developerWorks 全球站点上的
英文原文
。
-
面向 PHP 开发人员的 XML,第 1 部分: PHP XML 开发 15 分钟快速入门
(Cliff Morgan,developerWorks,2007 年 4 月):本系列的第一篇文章介绍了 PHP5 的 XML 实现,说明在 PHP 环境中使用 XML 多么简单。
-
面向 PHP 开发人员的 XML,第 2 部分: 高级 XML 解析技术
(Cliff Morgan,developerWorks,2007 年 4 月):本系列的第 2 部分讨论了 PHP5 中的 XML 解析技术,介绍如何判断哪种解析方法最适合您的应用程序。
-
面向 Perl 和 PHP 开发人员的 XML
:您可以通过该专题来了解更多与 Perl 和 PHP 相关的 XML 技术。
-
技巧: 压缩 XML 文件以便有效地传输
(Uche Ogbuji,developerWorks,2004 年 4 月):了解如何使用压缩技术处理 XML 以便通过 Web 服务进行传输。
-
技巧: 使用特定于语言的工具来进行 XML 处理
(Uche Ogbuji,developerWorks,2004 年 2 月):解析 XML 的时候可以尝试这些替代 SAX 和 DOM 的方法。
-
结合 Ajax 进行 PHP 开发,第 1 部分: 入门
和
结合 Ajax 进行 PHP 开发,第 2 部分: 后退、前进和刷新
(Sean Kelly,developerWorks,2006 年 9 月):这两篇文章完全使用 PHP 和 Simple Ajax Toolkit (Sajax) 创建了一个简单的相册在线 Web 应用程序。
-
改善 XML 的传输性能,第 1 部分
和
改善 XML 的传输性能,第 2 部分
(Dennis Sosnoski,developerWorks,2004 年 6 月):了解 XML 的备用非文本表示遇到的问题,以及这两篇文章中提出的解决之道。
-
Intuition and Binary XML
(Leigh Dodds,XML.com,2001 年 4 月):阅读关于 XML 的二进制编码替代方案的争论。
-
Workshop: XML in PHP5
:在线查看这份演讲稿。
-
XSLT 是什么类型的语言?
(Michael Kay,developerWorks,2001 年 2 月):从上下文中了解 XSLT 的来历、擅长方面以及使用它的原因。
-
技巧: 实现 XMLReader
(Benoît Marchal,developerWorks,2003 年 3 月):探讨 XML 管道 API。
-
用 PHP 读取和编写 XML DOM
(Jack Herrington,developerWorks,200 年 2 月):讨论读取 XML 的三种方法:DOM 库、SAX 解析器和正则表达式。此外还可以了解如何使用 DOM 和 PHP 文本模板编写 XML。
-
PHP 中的 SimpleXML 处理
(Elliotte Rusty Harold,developerWorks,2006 年 10 月):尝试使用 SimpleXML 扩展,能够帮助 PHP 页面实现查询、搜索、修改和重新发布 XML。
-
PHP V5 迁移指南
(Jack Herrington,developerWorks,2006 年 12 月):将 PHP V4 开发的代码迁移到 V5,大大改善代码的可维护性和稳定性。
-
Introducing Simple XML in PHP5
(Alejandro Gervasio,Dev Shed,2006 年 6 月):这是关于 SimpleXML 的系列文章的第一部分,利用 PHP5 simplexml 扩展简化工作,这个库主要用于解析简单的 XML 文件。
-
PHP Cookbook, Second Edition
(Adam Trachtenberg 和 David Sklar,O'Reilly Media,2006 年 8 月):学习构建可用于任何 Web 浏览器的动态 Web 应用程序。
-
XML.com
:关于 XML 世界的全面介绍请访问 O'Reilly 的 XML 站点。
-
W3C XML Information
:阅读 XML 规范。
-
PHP 开发官方站点
:了解这种被广泛采用的、特别适合 Web 开发的通用脚本语言。
-
Planet PHP
:请访问这个 PHP 开发人员社区新闻资源站点。
-
IBM XML 认证
:了解如何才能成为一名 IBM 认证的 XML 及相关技术的开发人员。
-
XML 技术文档库
:developerWorks 中国网站 XML 专区提供了大量技术文章和技巧、教程、标准以及 IBM 红皮书。
-
developerWorks 技术活动
和
网络广播
:随时关注技术的最新进展。
相关阅读 更多 +
排行榜 更多 +