DOM解析XML文档

PS:一说到DOM,我第一印象就是js处理html的节点数据.最近在编写采集程序的时候,同事向我推荐从属于PHP5内核的的DOM扩展解析html,经过四天查找php手册和文档了解使用DOM扩展完成采集程序后,对待采集我思路开阔了好多,以后不用再为写麻烦的正则解析表达式而烦恼了,DOM扩展能解决所有问题!而且速度也快了好多!下面就把总结的一些知识分享保留下来

  1. XML介绍

    1. XML文档实例分析 :xmldata.xml

                  <?xml version="1.0" encoding="UTF-8" ?>
                  
                      
                          bookTitle1
                          
                              author1
                          
                          bookTitle2
                          
                              author2
                          
                      
                  
                  
    2. XML文档-XML声明

      XML声明一般是XML文档的第一行

                  <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
                  

      XML声明由以下几个部分组成:
      version – -文档符合XML1.0规范,现在只有1.0
      encoding – -文档字符编码,默认为”UTF-8″
      standalone – -文档定义是否在一个文件内
      standalone=”yes”
      standalone=”no”

    3. XML文档-根元素

      每个XML文档必须有且只有一个根元素
      根元素是一个完全包括文档中其他所有元素的元素
      根元素的起始标记要放在所有其他元素的起始标记之前
      根元素的结束标记要放在所有其他元素的结束标记之后

    4. XML文档-标记 AND 属性

                      <title id="1">bookTitle1</title>
                       开始标记      文本      结束标记
                  

      1.一对标记是一个元素
      2.id=”1″作为 title元素的属性=>’id’ =>1

    5. XML文档-书写XML文件注意事项

      1.必须有XML声明语句
      <?xml version="1.0" encoding="UTF-8"?>
      2.必须有且仅有一个根元素
      3.标记大小写敏感,标记成对
      4.属性值用引号
      5.空标记关闭
      6.元素正确嵌套

  2. DOM 介绍

    1. DOM是Document Object Model的缩写,即文档对象模型,是W3C组件推荐的处理XML的标准接口,定义了所有文档元素的对象和属性,以及访问它们的方法(接口)。W3C文档对象模型(DOM)定义了访问诸如XML和XHTML文档的标准,是一个使程序和脚本有能力动态地访问和更新文档的内容、结构以及样式的平台和语言中立的接口
    2. DOM文档树模型

      DOM将一个XML文档以对象树的形式来表示,该对象树包含若干个节点,这些节点之间存在父子关系。每个节点是一个对象,代表XML文档的元素、属性、注释等。每个对象封装了操作DOM树的方法和属性
      DOM规范的核心就是树模型,对于要解析的XML文档,解析器会把XML文档加载到内存中,在内存中为XML文件建立逻辑形式的树。从本质上说,DOM就是XML文档的一个结构化的视图,它将一个XML文档看作是一棵节点树,而其中的每一个节点代表一个可以与其进行交互的对象。树的节点是一个个的对象这样通过操作这棵树和这些对象就可以完成对XML文档的操作,为处理文档的所有方面提供了一个完美的概念性框架。
      功能:
      1.载入整个XML文档并解析为节点树,以灵活多变的方式处理。
      2.遍历节点。
      3.获取某子树支下某类型的节点。
      4.直接获取指定的节点。

    3. 理解DOM

      节点(Node)
      标签(Tag、Mark)
      元素(Element)
      属性(Attribute)
      文本(Text、Cdata )
      1.一对严格封闭或一个自封闭的标签对应一个元素
      2.元素、属性和文本均为节点
      3.从根元素出发,整个XML形成一个完全由节点组成的树形体系
      4.元素节点构成分支,属性和文本节点构成树叶

    4. w3s Document 对象参考手册

      (*必看*)http://www.w3school.com.cn/xmldom/dom_document.asp

  3. PHP 5的DOM解析器

    1. DOMNode类
      DOMDocument类
      DOMNodeList类
      DOMElement类
      DOMText类
      DOMAttr类
      在DOM接口规范中,包含有多个接口。其中常用的基本接口有Document接口、Node接口、NodeList接口、Element接口、Text接口、Attr接口等接口。其中,Document接口是对文档进行操作的入口,它是从Node接口继承过来的。Node接口是其他大多数接口的父类,象Documet、Element、Attribute、Text等接口都是从Node接口继承过来的。NodeList接口是一个节点的集合,它包含了某个节点中的所有子节点
    2. XML的DOM模型的常用php操作

      DOMDocument([string version], [string encoding])

      可以使用new关键字初始化一个空的文档对象。如下:

      $doc = new DOMDocument('1.0');
                      #(加载文档前)文档的空格符和制表符操作(false:删除;true:保留)
                      preserveWhiteSpace(bool)
                      #装入XML文档:
                      #filename 本地或远程xml文件
                      load(string filename [, int options])
                      #source 仅仅xml字符串
                      loadXML(string source [, int options])
      
                      #输出XML之前,formatOutput属性设置为TRUE,可以美化文档的输出格式,使DOM解析器在文档中增加换行符,并向右缩进
                      formatOutput(bool)
                      输出DOMDocument对象内容:
                      #将XML文档输出到浏览器或做为标准标出(注意:也可以输出某个node的节点及其子节点,一般可以通过其打印出节点做测试用)
                      saveXML([DOMNode node [, integer options]])
                      #输出成本地文件
                      save(string filename [, integer options])
                  
                  #load 本地xml文件加载并美化输出浏览器
                  $doc = new DOMDocument();
                  $doc->preserveWhiteSpace = TRUE;
                  $doc->load('xmldata.xml');
                  $doc->formatOutput = TRUE;
                  echo $doc->saveXML();
                  var_dump($doc);//class DOMDocument#1 (0) { }
                  var_dump($doc->getElementsByTagName('title')); //class DOMNodeList#2 (0) { }
                  /*获取title节点总数*/
                  print_r($doc->getElementsByTagName('title')->length);//2
                  /*打印title第一个节点*/(saveXML一大作用)
                  echo $doc->saveXML($doc->getElementsByTagName('title')->item(0));
                  //bookTitle1
                  var_dump($doc->getElementsByTagName('title')->item(0));//class DOMElement#3 (0) { }
                  print_r($doc->getElementsByTagName('title')->item(0)->getAttribute('id'));//1
                  

      一定好好研究一下上例的返回值,具有借鉴作用奥

                  #load加载远程xml文件,并带http头信息
                  $opts = array(
                      'http' => array(
                          'user_agent' => 'PHP libxml agent',
                      )
                  );
                  $context = stream_context_create($opts);
                  libxml_set_streams_context($context);
                  // request a file through HTTP
                  $doc = DOMDocument::load('http://www.example.com/file.xml');
                  #
                  #loadXML xml字符串结构
                  $doc = new DOMDocument();
                  $doc->loadXML('<root><node/></root>');
                  echo $doc->saveXML();
                  #
                  #loadXML xml字符串结构2
                  $str = <<<XML
                  <?xml version="1.0" encoding="iso-8859-1"?>
                  <!DOCTYPE root [
                  <!ENTITY nbsp "&#160;">
                  ]>
                  <div>This&nbsp;is a non-breaking space.</div>
                  XML;
                  $dd2 = new DOMDocument();
                  $dd2->loadXML($str);
                  echo $dd2->saveXML();
                  #
                  /*案例编码问题:对于loadHTML加载节点中有中文存在的xml或者html字符串,
                  xml或html头部一定要有相应编码类型:例如:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
                  */
                  function loadNprepareHead($content,$encod='') {
                          //设置自动检测字符编码,以encoding_list
                          if (empty($encod))
                          $encod  = mb_detect_encoding($content,"ASCII,UTF-8,ISO-8859-1,windows-1252,iso-8859-15");
      
                          $headpos        = mb_strpos($content,'<head>');
                          if ($headpos === FALSE)
                                  $headpos= mb_strpos($content,'<HEAD>');
                          if ($headpos !== FALSE) {
                                  $headpos+=6;
                                  $content = mb_substr($content,0,$headpos) . '<meta http-equiv="Content-Type" content="text/html; charset='.$encod.'">' .mb_substr($content,$headpos);
                          }
                          return mb_convert_encoding($content, 'UTF-8', $encod);
                  }
                  //test_gb2312.html
                  $myhtml = <<<EOF
                  <html>
                  <head>
                  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">
                  <title>My Page</title>
                  </head>
                  <body>
                  <p><a href="/mypage1">斤斤计较就世界!</a></p>
                  <p><a href="/mypage2">Another Hello World!</a></p>
                  </body>
                  </html>
                  EOF;
                  $doc = new DOMDocument();
                  $myhtml = loadNprepareHead($myhtml);
                  $doc->loadHTML($myhtml);
                  print_r($doc->encoding);exit;
                  
    3. 错误处理机制

                      //用户错误处理(false开启错误显示,true关闭错误显示)
                      bool libxml_use_internal_errors ([ bool $use_errors = false ] )
                      //获得错误信息数组
                      array libxml_get_errors ()
                      //清除libxml的错误缓冲
                      libxml_clear_errors();
                      

      注意:libxml_use_internal_errors(true) 关闭错误显示

                      //开启错误显示//展示错误
                      libxml_use_internal_errors(false);
                      $doc = new DOMDocument;
                      if (!$doc->load('file.xml')) {
                          foreach (libxml_get_errors() as $error) {
                              echo $error;
                          }
                          libxml_clear_errors();
                      }
                      #延伸案例:通过php去验证其html的标签的严谨性
                      libxml_use_internal_errors(true);
                      $doc = new DOMDocument();
                      $doc->loadHTMLFile('http://www.baidu.com/');
                      print_r(libxml_get_errors());
                      libxml_clear_errors();
                  
    4. html的DOM模型的常用php操作

                      #(加载文档前)文档的空格符和制表符操作(false:删除;true:保留)
                      preserveWhiteSpace(bool)
                      #装入XML文档:
                      #filename 本地或远程html文件
                      loadHTMLFile(string filename)
                      #source 仅仅html字符串
                      loadHTML(string source )
                      #
                      #输出html之前,formatOutput属性设置为TRUE,很好的格式化输出缩进
                      formatOutput(bool)
                      输出DOMDocument对象内容:
                      #将html文档输出到浏览器或做为标准标出(注意:也可以输出某个node的节点及其子节点)
                      saveHTML ([ DOMNode $node = NULL ] )
                      #输出成本地文件
                      saveHTMLFile(string filename)
                      

      loadHTML或loadHTMLFile加载文件并在浏览器上显示

                      $doc = new DOMDocument();
                      $doc->loadHTML("Test");
                      //$doc->loadHTMLFile("filename.html");
                      //$doc->loadHTMLFile("www.baidu.com/filename.html");
                      echo $doc->saveHTML();
                      //echo $doc->saveHTMLFile("test4.html")
                      

      saveHTML 浏览器输出元素及其子元素信息

                      $doc = new DOMDocument;
                      $doc->loadHTML('<div><h1>Hello world!</h1></div>');
                      echo $doc->saveHTML($doc->getElementsByTagName("h1")->item(0));
                      //<h1>Hello world!</h1>
                      

      DOMXPath 采集举例

                      libxml_use_internal_errors(true) ;
                      $doc = new DOMDocument();
                      $doc->loadHTMLFile("http://www.youku.com/v_olist/c_97.html");
                      $doc->preserveWhiteSpace = TRUE;
                      $doc->formatOutput = TRUE;
                      $body = $doc->getElementsByTagName('body')->item(0);
                      $xpath = new DOMXPath($doc);
                      //xpath 获取元素节点
                      $path = "//ul[@class='p pv']";
                      $uls = $xpath->query($path,$body);
                      //echo $doc->saveHTML($uls->item(0));
                      foreach($uls as $ul) {
                          $lis = $ul->getElementsByTagName('li');
                          foreach($lis as $li) {
                              $as = $li->getElementsByTagName('a');
                              echo $as ->length.'';
                          }
                      }
                      

      注意:即使子标签只有一个,那他也是DOMNodeList对象所以也必须用item(0)下标表示

                      #saveHTMLFile 保存文件
                      $doc = new DOMDocument();
                      $doc->formatOutput = true;
                      $root = $doc->createElement("html");
                      $root = $doc->appendChild($root);
                      $head = $doc->createElement("head");
                      $head = $root->appendChild($head);
                      $title = $doc->createElement("title");
                      $title = $head->appendChild($title);
                      $text = $doc->createTextNode("This is the title你好");
                      $text = $title->appendChild($text);
                      echo "Wrote: " . $doc->saveHTMLFile("test4.html") . " bytes"; // Wrote: 129 bytes
                      

总结:


参考:

  1. PHP5的XML新特性

    
    http://blog.csdn.net/ice_berg16/article/details/52176#t0
    
    http://cn2.php.net/manual/en/domxpath.query.php
    
  2. 用 PHP 读取和编写 XML DOM

    
    http://www.ibm.com/developerworks/cn/opensource/os-xmldomphp/
    
    http://www.poluoluo.com/jzxy/201207/169778.html
    
  3. php使用DOM处理xml文档

    
    http://blog.sina.com.cn/s/blog_6066ce530100emr1.html
    

相关文章
  1. * 暂无相关文章
本站版权
1、本站所有主题由该文章作者发表,该文章作者与尘埃享有文章相关版权
2、其他单位或个人使用、转载或引用本文时必须同时征得该文章作者和尘埃的同意
3、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
4、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意
5、原文链接:
二维码
Posted in DOM解析, 编程语言
Comments are closed.