面向PHP开发人员的XML 第3部分: 读、操纵和写XML的高级技术
2008-11-19 22:26:04 来源:WEB开发网使用 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 示例代码
<?php
//This query does a search for any Web pages relevant to "xml(标准化越来越近了) Query"
$query = "http://api.search.yahoo.com/WebSearchService/V1/webSearch?".
"query=%5C%22xml(标准化越来越近了)%20Query%5C%22&appid=YahooDemo";
//Create the DOM Document object from the xml(标准化越来越近了) returned by the query
$xml(标准化越来越近了) = file_get_contents($query);
$dom = new DOMDocument;
$dom = DOMDocument::loadxml(标准化越来越近了)($xml(标准化越来越近了));
function xml(标准化越来越近了)_to_result($dom) {
//This function takes the xml(标准化越来越近了) document and maps it to a
//PHP object so that you can manipulate it later.
//First, retrieve the root element for the document
$root = $dom->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 "<p>The query returns ".$res["totalResultsAvailable"].
" total results The first 10 are as follows:</p>";
//Now loop through each of the actual results.
for($i=0; $i<$res['totalResultsReturned']; $i++) {
echo "<a href='".$res[$i]['ClickUrl']."'><b>".
$res[$i]['Title']."</b></a>: ";
echo $res[$i]['Summary'];
echo "<br /><br />";
}
?>
更多精彩
赞助商链接