柔情似水 发表于 2015-2-4 00:08:50

PHP编程:用PHP解析XSL

当然你可以把你最基本的功能放出来的时候就放出来,比如放到论坛上,让大家都参与,       用PHP解析XSL

    在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("^(+)://", $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 = $attribs;
    }
}

//处置元素的停止标头
function endElement($parser, $name) {
    $element = array_pop($this->stack);
    if(is_array($element)) {
      $element[] = $this->element;
      $this->element = $element;
    }else {
      $this->data = $this->element;
      $this->element = "";
    }
}

//处置字元材料标头
function characterData($parser, $data) {
    $data = eregi_replace("^ +","",$data);
    $data = eregi_replace("^\n+","",$data);
    if(strlen($data) > 0) {
      $this->element .= $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 = $dsn;
    }
}
//处置元素的入手下手标头
function startElement($parser, $name, $attribs) {
    if(eregi("^XSL:",$name)) {
      $ar = split(":",$name);
      return array_push($this->data,array(xsl => $ar,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"));
    }
}

//处置字元材料标头
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))
      if(eregi("/xsl",$key))
          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))
      return false;
    $root = $dsn;
    for($i=0;$i<count($root);$i++) {
      if($this->type) {
      if(eregi("^".$field."$",$root[$i])) {
          if(!$n--)
            return $root[$i];
      }
      }else {
      if(ereg("^".$field."$",$root[$i])) {
          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,1));
    // 检索数据指针
    $data = $this->find($this->dsn,$command);
    // 数据指针压入仓库
    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;
    // 检索数据指针
    $data = $this->find($dsn,$ar,$n);
    if($data) {
      // 如检索到,则轮回
      $ar++;
      array_push($this->datastack,$data);
      array_push($this->stack,$ar);
      $id = $ar;
    }
}
function value_of($command) {
    // 获得数据指针
    if(eregi("/",$command)) {
    }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);
    }
    print $data;
}
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
(
// 节点名





=> Array()
)
*************/
?>
不断巩固,摸透大部分PHP常用函数,并可理解OOP,MYSQL优化,以及模板

活着的死人 发表于 2015-2-4 09:24:08

作为一个合格的coder 编码的规范是必须,命名方面我推崇“驼峰法”,另外就是自己写的代码最好要带注释,不然时间长了,就算是自己的代码估计看起来都费事,更不用说别人拉。

小妖女 发表于 2015-2-9 21:15:38

我学习了一段时间后,我发现效果并不好(估计是我自身的问题)。因为一个人的精力总是有限的,同时学习这么多,会导致每个的学习时间都得不到保证。

精灵巫婆 发表于 2015-2-27 21:34:23

为了以后维护的方便最好是代码上都加上注释,“予人方便,自己方便”。此外开发文档什么的最好都弄齐全。我觉得这是程序员必备的素质。虽然会消耗点很多的时间。但是确实是非常有必要的。

若相依 发表于 2015-3-7 04:11:02

其实也不算什么什么心得,在各位大侠算是小巫见大巫了吧,望大家不要见笑,若其中有错误的地方请各位大虾斧正。

柔情似水 发表于 2015-3-10 22:49:00

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

老尸 发表于 2015-3-11 06:48:17

我还是推荐用firefox ,配上firebug 插件调试js能省下不受时间。谷歌的浏览器最好也不少用,因为谷歌的大侠们实在是太天才啦,把一些原来的js代码加了一些特效。

第二个灵魂 发表于 2015-3-11 15:51:39

写的比较杂,因为我也是个新手,不当至于大家多多指正。

只想知道 发表于 2015-3-18 22:59:30

对于初学者来说不推荐去拿钱买的。当然如果一个网站你经常去用,而且里面的资料也比较有用,最好还是买个会员比较好,毕竟那些也是别人的工作成果。

再现理想 发表于 2015-3-22 22:09:17

在我安装pear包的时候老是提示,缺少某某文件,才发现 那群extension 的排列是应该有一点的顺序,而我安装的版本的排序不是正常的排序。没办法我只好把那群冒号加了上去,只留下我需要使用的扩展。

飘飘悠悠 发表于 2015-3-24 22:35:06

本文当是我的笔记啦,遇到的问题随时填充

小魔女 发表于 2015-3-25 13:31:59

建议加几个专业的phper的群,当然啦需要说话的人多,一处一点问题能有人回答你的,当然啦要让人回答你的问题,平时就得躲在里面聊天,大家混熟啦,愿意回答你问题的人自然就多啦。

蒙在股里 发表于 2015-3-27 08:04:32

真正的方向了,如果将来要去开发团队,你一定要学好smarty ,phplib这样的模板引擎,

兰色精灵 发表于 2015-3-27 08:09:11

使用 jquery 等js框架的时候,要随时注意浏览器的更新情况,不然很容易发生框架不能使用。

莫相离 发表于 2015-3-27 11:10:56

如果你已经到这种程度了,那么你已经可以做我的老师了。其实php也分很多的区域,

分手快乐 发表于 2015-4-13 00:53:36

建数据库表的时候,int型要输入长度的,其实是个摆设的输入几位都没影响的,只要大于4就行,囧。

乐观 发表于 2015-4-16 00:11:19

本人接触php时间不长,算是phper中的小菜鸟一只吧。由于刚开始学的时候没有名师指,碰过不少疙瘩,呗很多小问题卡过很久,白白浪费不少宝贵的时间,在次分享一些子的学习的心得。

再见西城 发表于 2015-5-6 05:11:18

学习php的目的往往是为了开发动态网站,phper就业的要求也涵盖了很多。我大致总结为:精通php和mysql

简单生活 发表于 2015-6-13 01:57:41

我要在声明一下:我是个菜鸟!!我对php这门优秀的语言也是知之甚少。但是我要在这里说一下php在网站开发中最常用的几个功能:

飘灵儿 发表于 2015-7-6 02:05:06

环境搭建好,当你看见你的浏览器输出“it works\\\\\\\"时你一定是喜悦的。在你解决问题的时候,我强烈建议多读php手册。
页: [1]
查看完整版本: PHP编程:用PHP解析XSL