李大仁博客

php4/5使用Dom方式读取和解析和创建XML简单教程

今天CG做了一个简单的WP音乐播放器插件,其中涉及到使用PHP对XML文件的读取,解析和创建写入的功能,要求很多,整个开发过程做个教程应该足够了,CG自从上次修改了WP的部分源代码之后已近有好长时间没有写过php的程序,呵呵,有点生疏下面简单开始。

首先简单介绍一下XML(Extensible Markup Language),大家可以参阅http://baike.baidu.com/view/63.htm

简单的说就是一种通用的多环境多用途的标记存储语言,现在使用和广泛,这里不多介绍,XML实质上就是存储起来的字符流,更高级一点就是可以读取的字符串流,但是因为XML定义了它的文档格式,因而可以在尊重这一个格式的条件下使用多种方法对XML中的数据进行存取,这种方式叫XML解析,通常XML有DOM,正则式,saxXpath等多种解析和访问方式,这里CG今天简单讲讲PHP的DOM解析方式。


下面是简单的XML演示Demo

<?xml version="1.0" encoding="UTF-8" ?>
<!–a demo music list for freeware–>
 <playlist version="1" xmlns="http://xspf.org/ns/0/">
  <title>XSPF Playlist</title>
  <info>#</info>
  <trackList>
   <track>
     <annotation>Demo: Yanni – With An Orchid</annotation>
     <location>http://XXXX/WithanOrchid.Wma</location>
     <info></info>
   </track>
   <track>
     <annotation>Demo: Yanni – Ninghtingale</annotation>
     <location>http://XXXX/Ninghtingale.Wma</location>
     <info></info>
   </track>
  </trackList>
 </playlist>

需求1:获取trackList中所有track的annotation,location,info子节点的值。跟JS类似,获取所有track名称的Tag为数组,然后就是遍历一遍,因为要获取track下面的子节点的信息,不妨在遍历一遍track,因为格式固定,所以可以找到对应索引节点中的nodeValue就可以了。
源代码:
PHP5:

//PHP5
  $tracks = array();
  $playlistfile = 'XML File Path'; //XML File Path

  $playlistdom = new DOMDocument('1.0','utf-8');
  if (!$playlistdom->loadXML(file_get_contents($playlistfile)))
  {
    echo "Error while parsing the documentn";
    exit;
  }

  $items = $playlistdom->getElementsByTagName('track');

  foreach ($items as $item)
  {
  $annotation =$item->getElementsByTagName('annotation');
  $location =$item->getElementsByTagName('location');
  $info =$item->getElementsByTagName('info');
    $tracks[]=array(
      'annotation' => $annotation->item(0)->nodeValue,
      'location' => $location->item(0)->nodeValue,
      'info' => $info->item(0)->nodeValue );
  }
  print_r($tracks);

PHP4:

//PHP4
  $tracks = array();
  $playlistfile = 'XML File Path'; //XML File Path

  if (!$playlistdom = domxml_open_file($playlistfile)) {
   echo "Error while parsing the documentn";
   exit;
  }

  $items = $playlistdom->get_elements_by_tagname('track');
  foreach ($items as $item)
  {
    $annotation =$item->get_elements_by_tagname('annotation');
    $location =$item->get_elements_by_tagname('location');
    $info =$item->get_elements_by_tagname('info');
    $tracks[]=array(
      'title' => $annotation->item(0)->node_value,
      'path' =>$location->item(0)->node_value
      'info' => $info->item(0)->node_value );
  }
  print_r($tracks);

需求2:提供一个track数组,要求创建一个XML Dom对象。这里关键是对对象的遍历的过程的,需要从顶向下遍历这个对象然后依次创建Element,然后就是将Element中createTextNode设置它的值,最后记得appendChild到它的父节点就可以了。
源代码:
PHP5:

//PHP5
  $tracks=Array();//tracks
  $listdoc = new DOMDocument('1.0','UTF-8');
  $listroot = $listdoc->createElement('playlist');
  $listdoc->appendChild($listroot);
  $listtitle = $listdoc->createElement('title');
  $listtitle->appendChild($listdoc->createTextNode('XSPF Playlist'));
  $listroot->appendChild($listtitle);
  $listinfo = $listdoc->createElement('info');
  $listinfo->appendChild($listdoc->createTextNode('#'));
  $listroot->appendChild($listinfo);
  $listtracklist = $listdoc->createElement('trackList');
  $listroot->appendChild($listtracklist);
  foreach ( $tracks as $track)
  {
    $nodetrack = $listdoc->createElement('track');
      $nodeannotation = $listdoc->createElement('annotation');
      $nodeannotation -> appendChild($listdoc->createTextNode($track['title']));
      $nodetrack -> appendChild($nodeannotation);

      $nodelocation = $listdoc->createElement('location');
      $nodelocation -> appendChild($listdoc->createTextNode($track['path']));
      $nodetrack -> appendChild($nodelocation);

      $nodeinfo = $listdoc->createElement('info');
      $nodeinfo -> appendChild($listdoc->createTextNode('#'));
      $nodetrack -> appendChild($nodeinfo);
    $nodetrack = $listtracklist->appendChild($nodetrack);
  }
PHP4:
//PHP4
  $tracks=Array();//tracks
  $listdoc = domxml_new_doc('1.0');

  $listroot = $listdoc->create_element('playlist');
  $listdoc->append_child($listroot);
  $listtitle = $listdoc->create_element('title');
  $listtitle->append_child($listdoc->create_text_node('XSPF Playlist'));
  $listroot->append_child($listtitle);
  $listinfo = $listdoc->create_element('info');
  $listinfo->append_child($listdoc->create_text_node('#'));
  $listroot->append_child($listinfo);
  $listtracklist = $listdoc->create_element('trackList');
  $listroot->append_child($listtracklist);
  foreach ( $tracks as $track)
  {
    $nodetrack = $listdoc->create_element('track');
      $nodeannotation = $listdoc->create_element('annotation');
      $nodeannotation -> append_child($listdoc->create_text_node($track['title']));
      $nodetrack -> append_child($nodeannotation);

      $nodelocation = $listdoc->create_element('location');
      $nodelocation -> append_child($listdoc->create_text_node($track['path']));
      $nodetrack -> append_child($nodelocation);

      $nodeinfo = $listdoc->create_element('info');
      $nodeinfo -> append_child($listdoc->create_text_node('#'));
      $nodetrack -> append_child($nodeinfo);
    $nodetrack = $listtracklist->append_child($nodetrack);
  }

需求3:将PHP生成的XML Dom写入文件。
这个跟一般PHP写入文件类似,但是有两个比较重要的方法PHP下的SaveXML()和PHP4下的html_dump_mem();SaveXML是DomDocument对象的方法,这个很好理解,但是在PHP4下面,XML对象是当成HTML来处理的,所以用了一个大家以前处理HTML的方法html_dump_mem,由于XML>HTML,所以可以兼容。
源代码:
PHP5:

  $dom = DOMDocument(); //DOM
  $fileName = 'target FileName' ; //FileName
  $domFile = fopen($fileName,'w');
  if(!$domFile)
  {
    echo 'File open Error';
    exit;
  }
  fwrite($domFile, $dom->SaveXML());
  fclose($domFile);

PHP4:

  $dom = dom_xml(); //DOM,注意PHP4中没有dom_xml这个对象,$dom的实质是数组
  $fileName = 'target FileName' ; //FileName
  $domFile = fopen($fileName,'w');
  if(!$domFile)
  {
    echo 'File open Error';
    exit;
  }
  fwrite($domFile, $dom->html_dump_mem());
  fclose($domfile);
Exit mobile version