• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    用PHP解析XSL

    發布: 2007-7-14 19:53 | 作者: 佚名    | 來源: 網絡轉載     | 查看: 8次 | 進入軟件測試論壇討論

    領測軟件測試網     在php的應用當中,為做到數據和代碼分離需要使用模板技術。pear、phplib及不少公司都提供了相關的模板。但他們有一個共同的缺點:就是沒有統一的規范,給使用者帶來很多不便。另外有關的教程和范例較少,也太初淺,不易做深層次的開發應用。
        XSL是W3C組織的規范標準,隨著XML的應用而發展起來。其教程隨處可見,只要你有ie5就可使用。當然由于是新技術,在支持程度上尚顯不足。
        這里給大家介紹一種用用PHP解析XSL的方法。該方法僅使用PHP提供的XML函數,無須難以配置的XSLT。
        先看一下例子。
        將以下內容保存為resume.xml
    <?xml version="1.0" encoding="GB2312"?>
    <?xml:stylesheet type="text/xsl" href="resume2.xsl"?>
    <document>
    <resume>
      <alias>嘮叨</alias>
      <name>徐祖寧</name>
      <sex>男</sex>
      <birthday>1948.10</birthday>
      <addr>安徽</addr>
      <email>czjsz_ah@stats.gov.cn</email>
      <icq> </icq>
      <oicq> </oicq>
      <skill>C/C++、VFP、PHP、JavaScript</skill>
      <homepage> </homepage>
      <date>2001-7-19</date>
    </resume>
    <resume>
      <alias>刁饞</alias>
      <name>保密</name>
      <sex>男</sex>
      <birthday> </birthday>
      <addr>黑龍江</addr>
      <email>yuepengfei@mail.banner.com.cn</email>
      <icq>166581208</icq>
      <oicq>7665656</oicq>
      <skill> </skill>
      <homepage> </homepage>
      <date>2001-8-15</date>
    </resume>
    <resume>
      <alias>sports98</alias>
      <name>保密</name>
      <sex>男</sex>
      <birthday> </birthday>
      <addr>四川</addr>
      <email>flyruns@hotmail.com</email>
      <icq>15787767</icq>
      <oicq>11599322</oicq>
      <skill> </skill>
      <homepage>http://www.hiviresearch.com/cgi/report/</homepage>
      <date>2002-1-5</date>
    </resume>
    </document>

        將以下內容保存為resume1.xsl
    <?xml version="1.0" encoding="GB2312"?>
    <HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl">
    <HEAD>
    <TITLE>個人簡歷</TITLE>
    </HEAD><BODY>
    <TABLE border="1" cellspacing="0" style="font-size:10pt">
    <CAPTION style="font-size: 110%; font-weight: bold">
    版主信息
    </CAPTION>
    <xsl:for-each select="document">
    <TR>
    <TH>別名</TH>
    <TH>姓名</TH>
    <TH>性別</TH>
    <TH>所在地</TH>
    <TH>專長</TH>
    </TR>
    <xsl:for-each select="resume">
    <TR>
    <TD><xsl:value-of select="alias"/></TD>
    <TD><xsl:value-of select="name"/></TD>
    <TD><xsl:value-of select="sex"/></TD>
    <TD><xsl:value-of select="addr"/></TD>
    <TD><xsl:value-of select="skill"/></TD>
    </TR>
    </xsl:for-each>
    </xsl:for-each>
    </TABLE>
    </BODY>
    </HTML>

        將以下內容保存為resume2.xsl
    <?xml version="1.0" encoding="GB2312"?>
    <HTML xmlns:xsl="http://www.w3.org/TR/WD-xsl">
    <HEAD>
    <TITLE>個人簡歷</TITLE>
    </HEAD><BODY>
    <xsl:for-each select="document">
    <xsl:for-each select="resume">
    <TABLE border="1" cellspacing="0" style="font-size:10pt">
    <CAPTION style="font-size: 110%; font-weight: bold">
    版主信息
    </CAPTION>
    <TR>
    <TH>別名</TH><TD><xsl:value-of select="alias"/></TD>
    <TH>姓名</TH><TD><xsl:value-of select="name"/></TD>
    <TH>性別</TH><TD><xsl:value-of select="sex"/></TD>
    <TH>所在地</TH><TD><xsl:value-of select="addr"/></TD>
    </TR>
    <TR>
    <TH>加入時間</TH>
    <TD colspan="7"><xsl:value-of select="date"/></TD>
    </TR>
    <TR>
    <TH>專長</TH>
    <TD colspan="7"><xsl:value-of select="skill"/></TD>
    </TR>
    <TR>
    <TH>ICQ</TH>
    <TD colspan="7"><xsl:value-of select="icq"/></TD>
    </TR>
    <TR>
    <TH>OICQ</TH>
    <TD colspan="7"><xsl:value-of select="oicq"/></TD>
    </TR>
    <TR>
    <TH>主頁</TH>
    <TD colspan="7"><xsl:value-of select="homepage"/></TD>
    </TR>
    </TABLE>
    </xsl:for-each>
    </xsl:for-each>
    </BODY>
    </HTML>

        在ie5以上瀏覽器上查看resume.xml,并可修改resume.xml中<?xml:stylesheet type="text/xsl" href="resume2.xsl"?> 的resume2.xsl為resume1.xsl,可看到頁面的變化。當然由于不是所有的瀏覽器都支持這個轉換,所以需要在服務器上進行轉換。

        將以下內容保存為xmltest.php
    <?php
    require_once "xsl_class.php";
    $xml = new XML;
    $p = new XSL;
    $p->parser("resume2.xsl",$xml->parser("resume.xml"));
    $p->display();
    ?>
        變換其中的resume2.xsl,我們仍將看到不同的頁面,只是以轉變成HTML格式了。

       相關的類:
       類xml_class解析xml文檔產生一個類似于domxml的結構
       類xsl_class派生于xml_class,用于解析xsl文檔并模擬xsl函數,其中template尚未實現。
    *****************
       xml_class.php
    *****************
    <?php
    class Element {
      var $Element;  // 這種節點用于文檔中的任何元素。元素節點的子節點可以是其內容的元素節點、注釋節點、處理信息節點以及文本節點。
      var $Text;  // 文檔中出現的所有文本,都分組歸入到文本節點中。文本節點不可以有同為文本節點的緊接著的前或后的兄弟節點。
      var $Attribute; // 每一個元素節點都有一套自己附加的屬性節點。默認的屬性值以與指定屬性一樣的方法來處理。這些節點都沒有子節點。
      var $Namespace; // 對于每一個以xlmns:和屬性節點開頭的元素,都有一個名稱空格節點。這些節點沒有子節點。
      var $ProcessingInstruction; // 每一個處理指令都有一個單獨的節點。這些節點都沒有子節點。
      var $Comment; // 每一個都有一個注釋節點。這些節點都沒有子節點。
      var $parents = array();  
      var $childs = array();  
    }

    class xml {
      var $tm = array();
      var $xml_parser;
      var $data = array();
      var $element = ""; // 當前節點
      var $stack = array(); // 緩存當前標頭的相關參數
      var $type;

      function trustedFile($file) {
        // only trust local files owned by ourselves
        if (!eregi("^([a-z]+)://", $file)
            && fileowner($file) == getmyuid()) {
                return true;
        }
        return false;
      }

      //處理元素的開始標頭
      function startElement($parser, $name, $attribs) {
        if($this->element != "") {
          array_push($this->stack,$this->element);
        }
        $this->element = array(Name => $name);
        if(sizeof($attribs)) {
          $this->element[Attribute] = $attribs;
        }
      }

      //處理元素的結束標頭
      function endElement($parser, $name) {
        $element = array_pop($this->stack);
        if(is_array($element)) {
          $element[Element][] = $this->element;
          $this->element = $element;
        }else {
          $this->data[Root] = $this->element;
          $this->element = "";
        }
      }

      //處理字元資料標頭
      function characterData($parser, $data) {
        $data = eregi_replace("^ +","",$data);
        $data = eregi_replace("^\n+","",$data);
        if(strlen($data) > 0) {
          $this->element[Text] .= $data;
        }
      }

      //處理指令標頭
      function PIHandler($parser, $target, $data) {
        switch(strtolower($target)) {
          case "php":
            global $parser_file;
            // If the parsed document is "trusted", we say it is safe
            // to execute PHP code inside it.  If not, display the code
            // instead.
            if($this->trustedFile($parser_file[$parser])) {
              eval($data);
            } else {
              $this->tm[] = sprintf("Untrusted PHP code: <i>%s</i>",
                      htmlspecialchars($data));
            }
            break;
          default:
    //        echo $target;
    //        echo "==".$data;
    //        echo printf("%s %s",$target,$data);
            break;
        }
      }

      //處理內定標頭
      function defaultHandler($parser, $data) {
        if(substr($data, 0, 1) == "&" && substr($data, -1, 1) == ";") {
          $this->tm[] = sprintf('<font color="#aa00aa">%s</font>',
                  htmlspecialchars($data));
        }else {
          $this->tm[] = sprintf('<font size="-1">%s</font>',
                  htmlspecialchars($data));
        }
      }

      //處理外部實體參引標頭
      function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) {
        if ($systemId) {
          $p = new xml;
          return $p->parser($systemId);
        }
        return false;
      }

      function parser($file) {
        global $parser_file;

        if(!($fp = @fopen($file, "r"))) {
          return false;
        }
        $this->xml_parser = xml_parser_create();
        xml_set_object($this->xml_parser, &$this);  //使 XML 剖析器用對象

        xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, 1);
        xml_set_element_handler($this->xml_parser, "startElement", "endElement");
        xml_set_character_data_handler($this->xml_parser, "characterData");
        xml_set_processing_instruction_handler($this->xml_parser, "PIHandler");
        xml_set_default_handler($this->xml_parser, "defaultHandler");
        xml_set_external_entity_ref_handler($this->xml_parser, "externalEntityRefHandler");
        
        $this->type = xml_parser_get_option($this->xml_parser, XML_OPTION_CASE_FOLDING);
        while($data = fread($fp, 4096)) {
          if(!xml_parse($this->xml_parser, $data, feof($fp))) {
            die(sprintf("XML error: %s at line %d\n",
                        xml_error_string(xml_get_error_code($xml_parser)),
                        xml_get_current_line_number($xml_parser)));
            return false;
          }
        }
        xml_parser_free($this->xml_parser);
        return $this->data;
      }
    }
    ?>

    ********************
        xsl_class.php
    ********************

    <?php
    require_once "xml_class.php";

    class xsl extends xml {
      var $datastack = array();
      var $sp;
      function parser($file,$dsn=null) {
        parent::parser($file);
        if($dsn != null) {
          $this->dsn[Element][0] = $dsn[Root];
        }
      }
      //處理元素的開始標頭
      function startElement($parser, $name, $attribs) {
        if(eregi("^XSL:",$name)) {
          $ar = split(":",$name);
          return array_push($this->data,array(xsl => $ar[1],command => $attribs));
        }
        if(sizeof($attribs)) {
          $att = "";
          while(list($k, $v) = each($attribs)) {
            $att .= " $k=\"$v\"";
          }
          array_push($this->data,array(tag => "$name$att"));
        }else
          array_push($this->data,array(tag => "$name"));
      }

      //處理元素的結束標頭
      function endElement($parser, $name) {
        if(!eregi("^XSL:",$name)) {
          array_push($this->data,array(tag => "/$name"));
        }else {
          $ar = split(":",$name);
          array_push($this->data,array(xsl => "/$ar[1]"));
        }
      }

      //處理字元資料標頭
      function characterData($parser, $data) {
        $data = eregi_replace("^[ \n]+","",$data);
        if(strlen($data) > 0) {
          array_push($this->data,array(text => "$data"));
        }
      }

      //處理指令標頭
    //  function PIHandler($parser, $target, $data) {
    //  }

      //處理內定標頭
      function defaultHandler($parser, $data) {
      }

      //處理外部實體參引標頭
    //  function externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) {
    //  }

      // XSL指令解析
      function xsl_parser($i) {
        for(;$i<count($this->data);$i++) {
          $key = $this->data[$i];
          if(isset($key[xsl]))
            if(eregi("/xsl",$key[xsl]))
              return $i;
        }
      }

      // 從數據源讀取數據
      function get_data($ps) {
        if(! eregi("/",$ps)) {
          // 若是默認的層次
          $ps = join("/",$this->datastack)."/$ps";
        }
        return "[$ps]";
      }

      // 輸出結果
      function display() {
        $this->stack = array();  //初始化控制棧
        $this->datastack = array();  //初始化數據棧

        $type = true;  //用于控制text項的輸出
        for($id=0;$id<count($this->data);$id++) {
          $expr = $this->data[$id];
          list($key,$value) = each($expr);
          switch($key) {
            case "tag":
              echo "<".$value.">";
              if(eregi("^/",$value))
                echo "\n";
              break;
            case "text":
              if($type)
                echo $value;
              break;
            case "xsl":
    //          echo $value;
              list(,$command) = each($expr); // 取得操作集
              $value = eregi_replace("[/-]","_",strtolower($value));
              if(eregi("eval",$value))
                $value = eregi_replace("eval","xsl_eval",$value);
              $this->$value($command,$id);
              break;
          }
        }
      }
      // 檢索數據,$dsn開始的節點,$field節點名,$n匹配次數
      function find($dsn,$field,$n=0) {
        if(! isset($dsn[Element]))
          return false;
        $root = $dsn[Element];
        for($i=0;$i<count($root);$i++) {
          if($this->type) {
            if(eregi("^".$field."$",$root[$i][Name])) {
              if(!$n--)
                return $root[$i];
            }
          }else {
            if(ereg("^".$field."$",$root[$i][Name])) {
              if(!$n--)
                return $root[$i];
            }
          }
        }
        for($i=0;$i<count($root);$i++) {
          if($ar = $this->find($root[$i],$field,&$n))
            return $ar;
        }
        return false;
      }

      function for_each($command,&$id) {
        // 循環,將當前id壓入堆棧
        array_push($this->stack,array($id,$command[SELECT],1));
        // 檢索數據指針
        $data = $this->find($this->dsn,$command[SELECT]);
        // 數據指針壓入堆棧
        array_push($this->datastack,$data);
      }
      function _for_each($command,&$id) {
        // 取得入口地址
        $ar = array_pop($this->stack);
        // 拋棄當前數據指針
        array_pop($this->datastack);
        // 檢查是否為嵌套
        if(count($this->datastack) > 0) {
          $dsn = array_pop($this->datastack);
          array_push($this->datastack,$dsn);
        }else
          $dsn = $this->dsn;
        $n = $ar[2];
        // 檢索數據指針
        $data = $this->find($dsn,$ar[1],$n);
        if($data) {
          // 如檢索到,則循環
          $ar[2]++;
          array_push($this->datastack,$data);
          array_push($this->stack,$ar);
          $id = $ar[0];
        }
      }
      function value_of($command) {
        // 取得數據指針
        if(eregi("/",$command[SELECT])) {
        }else {
          if(count($this->datastack) > 0) {
            $dsn = array_pop($this->datastack);
            array_push($this->datastack,$dsn);
          }else
            $dsn = $this->dsn;
          $data = $this->find($dsn,$command[SELECT]);
        }
        print $data[Text];
      }
      function _value_of() {
      }
      function stylesheet() {
      }
      function _stylesheet() {
      }
      function template($command) {
    echo join(" ",$command)."<br>";
      }
      function _template() {
      }
      function apply_templates($command) {
    echo join(" ",$command)."<br>";
      }
      function _apply_templates() {
      }
      function xsl_eval() {
      }
      function _xsl_eval() {
      }
    }

    /**** 附錄 ****
    數據元素節點
    Array
    (
      [Name] // 節點名
      [Text]
      [Attribute]
      [Namespace]
      [Comment]
      [ProcessingInstruction]
      [Element] => Array()
    )
    *************/
    ?>

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>