浅谈如何利用PHP访问和操作DOM(1)
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
- <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
- <book>
- <!--XML Processing [part I] -->
- <name>XML Processing I</name>
- <author>John Smith Jr.</author>
- <publisher>HisOwnTM</publisher>
- <ISBN>111-222-333-4441</ISBN>
- <contents>
- <chapter_I>
- <title>What is XML about ?</title>
- <content>XML (Extensible Markup Language) is a ...</content>
- </chapter_I>
- <chapter_II>
- <title>SAX</title>
- <content>SAX is a simple API for ...</content>
- </chapter_II>
- <chapter_III>
- <title>StAX</title>
- <content>Much powerful and flexible, StAX, is very...</content>
- </chapter_III>
- <chapter_IV>
- <title>DOM
- <subtitle>DOM concept
- <continut>Starting to use DOM...</continut>
- </subtitle>
- <subchapter_IV_I>
- <title>First DOM application...</title>
<content>Here it is your first DOM application...</content> - </subchapter_IV_I>
- </title>
- </chapter_IV>
- <end>The end...</end>
- </contents>
- <!-- See you in XML Processing [part II] -->
- </book>
先下载本文使用的PHP代码压缩包,http://assets.devx.com/sourcecode/41975_oa_mainsource.zip,将Book.xml和压 缩包解压后放在同一个目录下。
第一个示例应用程序使用Book.xml文档,提取出关联的树,然后使用DOMElement接口的getElementsByTagName方法显示第一个子节点实例:
DOMNodeList DOMElement::getElementsByTagName(string $name):这个方法返回所有$name参数指定的标签名的子元素。下面的例子查找<book>根节点 ,然后查找它的子节点 <author>,<publisher>和 <name>元素,选择每个子节点的第一个,最后打印这些节点的值:
- <?php
- // 创建一个文档实例
- $doc = new DOMDocument();
- //载入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子树,并列出节点的名字和值。
- 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);
- }
- }
- }
上面的例子使用下面的条件去除了所有空文本节点,让输出看起来更干净:
- if (($subNode->nodeType != 3) ||
- (($subNode->nodeType == 3) &&
- (strlen(trim($subNode->wholeText))>=1)))
前面的代码检查节点是否被处理,同样,你可以设置预定义的preserveWhiteSpace属性,它移除冗余的空白,默认值是TRUE。
为了测试这个功能,下面这个例子传递Book.xml文档的根节点给递归函数getNodesInfo,然后打印出整个DOM树的标签和值:
- <?php
- //创建一个文档实例
- $doc = new DOMDocument();
- //载入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的部分输出内容
PHP之友评论