浅谈如何利用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

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
  2. <book> 
  3. <!--XML Processing [part I] --> 
  4.  <name>XML Processing I</name> 
  5.   <author>John Smith Jr.</author> 
  6.   <publisher>HisOwnTM</publisher> 
  7.   <ISBN>111-222-333-4441</ISBN> 
  8.   <contents> 
  9.     <chapter_I> 
  10.       <title>What is XML about ?</title> 
  11.       <content>XML (Extensible Markup Language) is a ...</content> 
  12.     </chapter_I> 
  13.     <chapter_II> 
  14.       <title>SAX</title> 
  15.       <content>SAX is a simple API for ...</content> 
  16.    </chapter_II> 
  17.     <chapter_III> 
  18.       <title>StAX</title> 
  19.       <content>Much powerful and flexible, StAX, is very...</content> 
  20.     </chapter_III> 
  21.     <chapter_IV> 
  22.       <title>DOM 
  23.         <subtitle>DOM concept  
  24.           <continut>Starting to use DOM...</continut> 
  25.         </subtitle> 
  26.         <subchapter_IV_I> 
  27.          <title>First DOM application...</title> 
  28.           <content>Here it is your first DOM application...</content> 
  29.         </subchapter_IV_I>  
  30.       </title>              
  31.     </chapter_IV>           
  32.     <end>The end...</end>           
  33.   </contents> 
  34. <!-- See you in XML Processing [part II] --> 
  35. </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>元素,选择每个子节点的第一个,最后打印这些节点的值:

  1. <?php 
  2.  // 创建一个文档实例  
  3.   $doc = new DOMDocument();  
  4.   //载入Book.xml文件  
  5.   $doc->load( 'Book.xml' );  
  6.   //使用book标签名搜索所有元素  
  7.   $books = $doc->getElementsByTagName( "book" );  
  8.   //使用author标签名搜索所有元素  
  9.   $authors = $doc->getElementsByTagName( "author" );  
  10.   //返回第一个标签名为author的元素  
  11.   $author = $authors->item(0)->nodeValue;  
  12.   //以publisher标签名搜索所有元素 
  13.   $publishers = $doc->getElementsByTagName( "publisher" );  
  14.   //返回第一个找到的标签名为publisher的元素  
  15.    $publisher = $publishers->item(0)->nodeValue;  
  16.   //搜索标签名为name的所有元素 
  17.   $titles = $doc->getElementsByTagName( "name" );  
  18.   //返回标签名为name的第一个找到的元素  
  19.   $title = $titles->item(0)->nodeValue;  
  20.   //打印找到的值  
  21.   echo "$title - $author - $publisher \n";  
  22.  ?> 

最后一行是打印第一个标题,第一个作者,第一个出版商,使用连字符分隔,输出:


XML Processing I - John Smith Jr. - HisOwnTM


递归浏览DOM树


因为XML文档结构中一个标签可以包括另一个标签(分支树),剩下就是叶子节点,因此你可以浏览完整的树或从任何节点开始递归浏览子树 。下面的例子是从任何开始节点($node)浏览下面的XML子树,并列出节点的名字和值。

  1. function getNodesInfo($node)  
  2. {  
  3.    if ($node->hasChildNodes())  
  4.    {  
  5.       $subNodes = $node->childNodes; 
  6.       foreach ($subNodes as $subNode)  
  7.       { 
  8.          if (($subNode->nodeType != 3) ||   
  9.             (($subNode->nodeType == 3) &&  
  10.             (strlen(trim($subNode->wholeText))>=1)))     
  11.          {  
  12.             echo "Node name: ".$subNode->nodeName."\n";  
  13.             echo "Node value: ".$subNode->nodeValue."\n";  
  14.          }  
  15.          getNodesInfo($subNode);           
  16.       }  
  17.    }
            
  18. }    

上面的例子使用下面的条件去除了所有空文本节点,让输出看起来更干净:

  1. if (($subNode->nodeType != 3) ||   
  2.    (($subNode->nodeType == 3) &&  
  3.    (strlen(trim($subNode->wholeText))>=1)))    

前面的代码检查节点是否被处理,同样,你可以设置预定义的preserveWhiteSpace属性,它移除冗余的空白,默认值是TRUE。


为了测试这个功能,下面这个例子传递Book.xml文档的根节点给递归函数getNodesInfo,然后打印出整个DOM树的标签和值:

  1. <?php 
  2. //创建一个文档实例   
  3. $doc = new DOMDocument();  
  4. //载入Book.xml文件  
  5. $doc->load( 'Book.xml' );   
  6. //设置对象树根   
  7. $root = $dom->firstChild;  
  8. // 递归函数列出子树的所有节点  
  9. function getNodesInfo($node)  
  10. {  
  11.    if ($node->hasChildNodes())  
  12.    {  
  13.       $subNodes = $node->childNodes;  
  14.      foreach ($subNodes as $subNode)  
  15.       {  
  16.          if (($subNode->nodeType != 3) ||   
  17.             (($subNode->nodeType == 3)    
  18.             &&(strlen(trim($subNode->wholeText))>=1)))     
  19.          {  
  20.          echo "Node name: ".$subNode->nodeName."\n";  
  21.          echo "Node value: ".$subNode->nodeValue."\n";  
  22.      }  
  23.       getNodesInfo($subNode);           
  24.       }  
  25.    }        
  26. }     
  27. //调用getNodesInfo函数  
  28. getNodesInfo($root);  
  29. ?> 

显示输出的小部分内容


 图1显示了输出的小部分内容


图- 1文档内容:这个图显示了通过getNodesInfo递归函数运行Book.xml的部分输出内容





标签:

友情链接
轻松育儿世界奇观
苏ICP备16066217号-2