백엔드 개발 PHP 튜토리얼 用PHP解析XSL_PHP

用PHP解析XSL_PHP

Jun 01, 2016 pm 12:36 PM
data function if 마디 분석하다

    用PHP解析XSL

    在php的应用当中,为做到数据和代码分离需要使用模板技术。pear、phplib及不少公司都提供了相关的模板。但他们有一个共同的缺点:就是没有统一的规范,给使用者带来很多不便。另外有关的教程和范例较少,也太初浅,不易做深层次的开发应用。
    XSL是W3C组织的规范标准,随着XML的应用而发展起来。其教程随处可见,只要你有ie5就可使用。当然由于是新技术,在支持程度上尚显不足。
    这里给大家介绍一种用用PHP解析XSL的方法。该方法仅使用PHP提供的XML函数,无须难以配置的XSLT。
    先看一下例子。
    将以下内容保存为resume.xml




  唠叨
  徐祖宁
  
  1948.10
  安徽
  czjsz_ah@stats.gov.cn
   
   
  C/C++、VFP、PHP、JavaScript
   
  2001-7-19


  刁馋
  保密
  
   
  黑龙江
  yuepengfei@mail.banner.com.cn
  166581208
  7665656
   
   
  2001-8-15


  sports98
  保密
  
   
  四川
  flyruns@hotmail.com
  15787767
  11599322
   
  http://www.hiviresearch.com/cgi/report/
  2002-1-5



    将以下内容保存为resume1.xsl



个人简历






















版主信息
别名 姓名 性别 所在地 专长




    将以下内容保存为resume2.xsl



个人简历
































版主信息
别名 姓名 性别 所在地
加入时间
专长
ICQ
OICQ
主页






    在ie5以上浏览器上查看resume.xml,并可修改resume.xml中 的resume2.xsl为resume1.xsl,可看到页面的变化。当然由于不是所有的浏览器都支持这个转换,所以需要在服务器上进行转换。

    将以下内容保存为xmltest.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
*****************
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: %s",
                  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('%s',
              htmlspecialchars($data));
    }else {
      $this->tm[] = sprintf('%s',
              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
********************

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(;$idata);$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;$iddata);$id++) {
      $expr = $this->data[$id];
      list($key,$value) = each($expr);
      switch($key) {
        case "tag":
          echo "";
          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       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       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)."
";
  }
  function _template() {
  }
  function apply_templates($command) {
echo join(" ",$command)."
";
  }
  function _apply_templates() {
  }
  function xsl_eval() {
  }
  function _xsl_eval() {
  }
}

/**** 附录 ****
数据元素节点
Array
(
  [Name] // 节点名
  [Text]
  [Attribute]
  [Namespace]
  [Comment]
  [ProcessingInstruction]
  [Element] => Array()
)
*************/
?>
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

여러 조건을 판단하기 위해 C 언어로 작성하는 방법 여러 조건을 판단하기 위해 C 언어로 작성하는 방법 Mar 25, 2024 pm 03:24 PM

C 언어에서 if 문은 일반적으로 단일 조건에 따라 특정 코드 블록을 실행하는 데 사용됩니다. 그러나 여러 조건을 결합하여 &&, || 및 !와 같은 논리 연산자를 사용하여 결정을 내릴 수 있습니다. 여러 조건을 판단하기 위해 논리적 AND(&&)를 사용하고, 하나 이상의 조건을 판단하기 위해 논리적 OR(||)를 사용하고, 단일 조건의 부정을 판단하기 위해 논리적 NOT(!)을 사용하고, if 문을 중첩하고 괄호를 사용하는 것을 포함합니다. 우선순위를 명확히 하기 위해.

HTTP 상태 코드 460의 의미와 사용법에 대한 심층 분석 HTTP 상태 코드 460의 의미와 사용법에 대한 심층 분석 Feb 18, 2024 pm 08:29 PM

HTTP 상태 코드 460의 역할 및 응용 시나리오에 대한 심층 분석 HTTP 상태 코드는 웹 개발에서 매우 중요한 부분이며 클라이언트와 서버 간의 통신 상태를 나타내는 데 사용됩니다. 그중 HTTP 상태 코드 460은 상대적으로 특별한 상태 코드입니다. 이 기사에서는 해당 역할과 애플리케이션 시나리오를 심층적으로 분석합니다. HTTP 상태 코드 460의 정의 HTTP 상태 코드 460의 구체적인 정의는 "ClientClosedRequest"이며, 이는 클라이언트가 요청을 닫는다는 의미입니다. 이 상태 코드는 주로 다음을 나타내는 데 사용됩니다.

iBatis와 MyBatis: 비교 및 ​​장점 분석 iBatis와 MyBatis: 비교 및 ​​장점 분석 Feb 18, 2024 pm 01:53 PM

iBatis 및 MyBatis: 차이점 및 장점 분석 소개: Java 개발에서 지속성은 일반적인 요구 사항이며 iBatis와 MyBatis는 널리 사용되는 두 가지 지속성 프레임워크입니다. 유사점이 많지만 몇 가지 중요한 차이점과 장점도 있습니다. 이 기사에서는 이 두 프레임워크의 기능, 사용법 및 샘플 코드에 대한 자세한 분석을 통해 독자에게 보다 포괄적인 이해를 제공할 것입니다. 1. iBatis 기능: iBatis는 SQL 매핑 파일을 사용하는 오래된 지속성 프레임워크입니다.

Oracle 오류 3114에 대한 자세한 설명: 신속하게 해결하는 방법 Oracle 오류 3114에 대한 자세한 설명: 신속하게 해결하는 방법 Mar 08, 2024 pm 02:42 PM

Oracle 오류 3114에 대한 자세한 설명: 이를 신속하게 해결하는 방법, 구체적인 코드 예제가 필요합니다. Oracle 데이터베이스를 개발 및 관리하는 동안 다양한 오류가 발생하는 경우가 많으며 그중 오류 3114는 비교적 일반적인 문제입니다. 오류 3114는 일반적으로 네트워크 오류, 데이터베이스 서비스 중지 또는 잘못된 연결 문자열 설정으로 인해 발생할 수 있는 데이터베이스 연결 문제를 나타냅니다. 이 문서에서는 오류 3114의 원인과 이 문제를 신속하게 해결하는 방법을 자세히 설명하고 특정 코드를 첨부합니다.

웜홀 NTT 구문 분석: 모든 토큰을 위한 개방형 프레임워크 웜홀 NTT 구문 분석: 모든 토큰을 위한 개방형 프레임워크 Mar 05, 2024 pm 12:46 PM

Wormhole은 블록체인 상호 운용성의 선두주자로서 소유권, 통제 및 무허가형 혁신을 우선시하는 탄력적이고 미래 지향적인 분산 시스템을 만드는 데 중점을 두고 있습니다. 이 비전의 기초는 단순성, 명확성 및 광범위한 다중 체인 솔루션 제품군으로 상호 운용성 환경을 재정의하기 위한 기술 전문 지식, 윤리적 원칙 및 커뮤니티 조정에 대한 헌신입니다. 영지식 증명, 확장 솔루션 및 풍부한 기능의 토큰 표준이 등장하면서 블록체인은 더욱 강력해지고 상호 운용성은 점점 더 중요해지고 있습니다. 이 혁신적인 애플리케이션 환경에서 새로운 거버넌스 시스템과 실용적인 기능은 네트워크 전반의 자산에 전례 없는 기회를 제공합니다. 프로토콜 빌더는 이제 이 새로운 멀티체인에서 어떻게 기능할지 고민하고 있습니다.

PHP에서 중간점의 의미와 사용법 분석 PHP에서 중간점의 의미와 사용법 분석 Mar 27, 2024 pm 08:57 PM

[PHP 중간점의 의미와 사용법 분석] PHP에서 중간점(.)은 두 개의 문자열이나 객체의 속성이나 메소드를 연결하는 데 사용되는 일반적으로 사용되는 연산자입니다. 이 기사에서는 구체적인 코드 예제를 통해 PHP에서 중간점의 의미와 사용법을 자세히 살펴보겠습니다. 1. 문자열 중간점 연산자 연결 PHP에서 가장 일반적인 사용법은 두 문자열을 연결하는 것입니다. 두 문자열 사이에 .을 배치하면 두 문자열을 이어붙여 새 문자열을 만들 수 있습니다. $string1=&qu

Win11의 새로운 기능 분석: Microsoft 계정 로그인을 건너뛰는 방법 Win11의 새로운 기능 분석: Microsoft 계정 로그인을 건너뛰는 방법 Mar 27, 2024 pm 05:24 PM

Win11의 새로운 기능 분석: Microsoft 계정 로그인을 건너뛰는 방법 Windows 11이 출시되면서 많은 사용자는 Windows 11이 더 편리하고 새로운 기능을 제공한다는 사실을 알게 되었습니다. 그러나 일부 사용자는 시스템을 Microsoft 계정에 연결하는 것을 좋아하지 않아 이 단계를 건너뛰기를 원할 수도 있습니다. 이 문서에서는 사용자가 Windows 11에서 Microsoft 계정 로그인을 건너뛰고 보다 개인적이고 자율적인 환경을 달성하는 데 도움이 되는 몇 가지 방법을 소개합니다. 먼저 일부 사용자가 Microsoft 계정에 로그인하기를 꺼리는 이유를 이해해 보겠습니다. 한편으로는 일부 사용자들은 다음과 같은 걱정을 합니다.

Apache2는 PHP 파일을 올바르게 구문 분석할 수 없습니다. Apache2는 PHP 파일을 올바르게 구문 분석할 수 없습니다. Mar 08, 2024 am 11:09 AM

공간 제한으로 인해 다음은 간략한 기사입니다. Apache2는 일반적으로 사용되는 웹 서버 소프트웨어이고 PHP는 널리 사용되는 서버측 스크립팅 언어입니다. 웹 사이트를 구축하는 과정에서 Apache2가 PHP 파일을 올바르게 구문 분석할 수 없어 PHP 코드가 실행되지 않는 문제가 발생하는 경우가 있습니다. 이 문제는 일반적으로 Apache2가 PHP 모듈을 올바르게 구성하지 않거나 PHP 모듈이 Apache2 버전과 호환되지 않기 때문에 발생합니다. 이 문제를 해결하는 방법은 일반적으로 두 가지가 있는데, 그 중 하나는

See all articles