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

Python解析XML中的特殊字符和转义序列XML(eXtensibleMarkupLanguage)是一种常用的数据交换格式,用于在不同系统之间传输和存储数据。在处理XML文件时,经常会遇到包含特殊字符和转义序列的情况,这可能会导致解析错误或者误解数据。因此,在使用Python解析XML文件时,我们需要了解如何处理这些特殊字符和转义序列。一、特殊字符和

Python编程解析百度地图API文档中的坐标转换功能导读:随着互联网的快速发展,地图定位功能已经成为现代人生活中不可或缺的一部分。而百度地图作为国内最受欢迎的地图服务之一,提供了一系列的API供开发者使用。本文将通过Python编程,解析百度地图API文档中的坐标转换功能,并给出相应的代码示例。一、引言在开发中,我们有时会涉及到坐标的转换问题。百度地图AP

使用Python解析SOAP消息SOAP(SimpleObjectAccessProtocol)是一种基于XML的远程过程调用(RPC)协议,用于在网络上不同的应用程序之间进行通信。Python提供了许多库和工具来处理SOAP消息,其中最常用的是suds库。suds是Python的一个SOAP客户端库,可以用于解析和生成SOAP消息。它提供了一种简单而

随着PHP8.0的发布,许多新特性都被引入和更新了,其中包括XML解析库。PHP8.0中的XML解析库提供了更快的解析速度和更好的可读性,这对于PHP开发者来说是一个重要的提升。在本文中,我们将探讨PHP8.0中的XML解析库的新特性以及如何使用它。什么是XML解析库?XML解析库是一种软件库,用于解析和处理XML文档。XML是一种用于将数据存储为结构化文档

使用Python解析带有命名空间的XML文档XML是一种常用的数据交换格式,能够适应各种应用场景。在处理XML文档时,有时会遇到带有命名空间(namespace)的情况。命名空间可以防止不同XML文档中元素名的冲突,提高了XML的灵活性和可扩展性。本文将介绍如何使用Python解析带有命名空间的XML文档,并给出相应的代码示例。首先,我们需要导入xml.et

PHP中的HTTPBasic鉴权方法解析及应用HTTPBasic鉴权是一种简单但常用的身份验证方法,它通过在HTTP请求头中添加用户名和密码的Base64编码字符串进行身份验证。本文将介绍HTTPBasic鉴权的原理和使用方法,并提供PHP代码示例供读者参考。一、HTTPBasic鉴权原理HTTPBasic鉴权的原理非常简单,当客户端发送一个请求时

PHP爬虫是一种自动化获取网页信息的程序,它可以获取网页代码、抓取数据并存储到本地或数据库中。使用爬虫可以快速获取大量的数据,为后续的数据分析和处理提供巨大的帮助。本文将介绍如何使用PHP实现一个简单的爬虫,以获取网页源码和内容解析。一、获取网页源码在开始之前,我们应该先了解一下HTTP协议和HTML的基本结构。HTTP是HyperText

PHP中的单点登录(SSO)鉴权方法解析引言:随着互联网的发展,用户通常要同时访问多个网站进行各种操作。为了提高用户体验,单点登录(SingleSign-On,简称SSO)应运而生。本文将探讨PHP中的SSO鉴权方法,并提供相应的代码示例。一、什么是单点登录(SSO)?单点登录(SSO)是一种集中化认证的方法,在多个应用系统中,用户只需要登录一次,就能访问


핫 AI 도구

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

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

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

WebStorm Mac 버전
유용한 JavaScript 개발 도구

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기
