DOM树定义了文档的逻辑结构,以及控制你访问和操作这些文档的方法。使用DOM,开发人员可以创建XML或HTML文档,操作它们的结果,增加、修改和删除文档 元素及内容。可以从任何编程语言访问DOM,本文使用PHP 5 DOM扩展,它是PHP核心的一部分,因此除了PHP外,不需要安装其它软件。
DOM树节点遵循XML命名规范,如:
1、Document节点 -- 表示DOMDocument接口
2、Element节点 -- 表示DOMElement接口
3、Attribute节点 -- 表示DOMAttr接口
4、Comment节点 -- 表示DOMComment接口
5、Text节点 -- 表示DOMText接口
提取元素
这一小节介绍如何从DOM树中提取元素和值,本文使用Book.xml作为例子进行说明,其内容如清单1所示。
清单1 Book.xml<?xmlversion ="1.0"encoding="UTF-8"standalone="yes"?>
XML Processing I
John Smith Jr.
HisOwnTM
111-222-333-4441
What is XML about ?XML (Extensible Markup Language) is a ...
SAXSAX is a simple API for ...
StAXMuch powerful and flexible, StAX, is very...
DOMDOM concept
Starting to use DOM...
First DOM application...Here it is your first DOM application...
The end...
第一个示例应用程序使用Book.xml文档,提取出关联的树,然后使用DOMElement接口的getElementsByTagName方法显示第一个子节点实例:
DOMNodeList DOMElement::getElementsByTagName(string $name):这个方法返回所有$name参数指定的标签名的子元素。下面的例子查找根节点 ,然后查找它的子节点 ,和 元素,选择每个子节点的第一个,最后打印这些节点的值:<?php
// 创建一个文档实例
$doc=newDOMDocument();
//载入Book.xml文件
$doc->load( 'Book.xml' );
//使用book标签名搜索所有元素
$books= $doc->getElementsByTagName( "book" );
//使用author标签名搜索所有元素
$authors= $doc->getElementsByTagName( "author" );
//返回第一个标签名为author的元素
$author= $authors->item(0)->nodeValue;
//以publisher标签名搜索所有元素
$publishers= $doc->getElementsByTagName( "publisher" );
//返回第一个找到的标签名为publisher的元素
$publisher= $publishers->item(0)->nodeValue;
//搜索标签名为name的所有元素
$titles= $doc->getElementsByTagName( "name" );
//返回标签名为name的第一个找到的元素
$title= $titles->item(0)->nodeValue;
//打印找到的值
echo "$title - $author - $publisher \n";
?>
最后一行是打印第一个标题,第一个作者,第一个出版商,使用连字符分隔,输出:
XML Processing I - John Smith Jr. - HisOwnTM
递归浏览DOM树
因为XML文档结构中一个标签可以包括另一个标签(分支树),剩下就是叶子节点,因此你可以浏览完整的树或从任何节点开始递归浏览子树 。下面的例子是从任何开始节点($node)浏览下面的XML子树,并列出节点的名字和值。functiongetNodesInfo($node)
{
if($node->hasChildNodes())
{
$subNodes=$node->childNodes;
foreach($subNodesas$subNode)
{
if(($subNode->nodeType != 3) ||
(($subNode->nodeType == 3) &&
(strlen(trim($subNode->wholeText))>=1)))
{
echo"Node name: ".$subNode->nodeName."\n";
echo"Node value: ".$subNode->nodeValue."\n";
}
getNodesInfo($subNode);
}
}
}
上面的例子使用下面的条件去除了所有空文本节点,让输出看起来更干净:if (($subNode->nodeType != 3) ||
(($subNode->nodeType== 3) &&
(strlen(trim($subNode->wholeText))>=1)))
前面的代码检查节点是否被处理,同样,你可以设置预定义的preserveWhiteSpace属性,它移除冗余的空白,默认值是TRUE。
为了测试这个功能,下面这个例子传递Book.xml文档的根节点给递归函数getNodesInfo,然后打印出整个DOM树的标签和值:<?php
//创建一个文档实例
$doc=newDOMDocument();
//载入Book.xml文件
$doc->load( 'Book.xml' );
//设置对象树根
$root= $dom->firstChild;
// 递归函数列出子树的所有节点
function getNodesInfo($node)
{
if ($node->hasChildNodes())
{
$subNodes= $node->childNodes;
foreach ($subNodes as $subNode)
{
if (($subNode->nodeType != 3) ||
(($subNode->nodeType== 3)
&&(strlen(trim($subNode->wholeText))>=1)))
{
echo "Node name: ".$subNode->nodeName."\n";
echo "Node value: ".$subNode->nodeValue."\n";
}
getNodesInfo($subNode);
}
}
}
//调用getNodesInfo函数
getNodesInfo($root);
?>
图1显示了输出的小部分内容
图- 1文档内容:这个图显示了通过getNodesInfo递归函数运行Book.xml的部分输出内容