PHP を使用して XSL を解析します
PHP アプリケーションでは、データとコードを分離するためにテンプレート テクノロジーが必要です。 pear、phplib、および多くの企業が関連テンプレートを提供しています。しかし、共通の欠点があります。それは、統一された仕様がないため、ユーザーに多大な不便をもたらしているということです。さらに、関連するチュートリアルや例がほとんどなく、基本的すぎて詳細な開発や応用を行うのが困難です。
XSL は W3C 組織の仕様標準であり、XML を応用して開発されました。そのチュートリアルはどこにでもあります。ie5 を持っている限り、それを使用できます。もちろん、新しい技術なのでサポートレベルはまだまだ不十分です。
ここではPHPを使ってXSLを解析する方法を紹介します。この方法は、PHP が提供する XML 関数のみを使用し、設定の難しい XSLT を必要としません。
まずは例を見てみましょう。
次のコンテンツをresume.xmlとして保存します
> ;
<ドキュメント>
<履歴書>
<別名>/別名>
<名前名前>
<誕生日> 1948.10< ;/誕生日>
安徽
czjsz_ah@stats.gov.cn
< /oicq>
、VFP、PHP、JavaScriptスキル>
<履歴書>
<名前>秘密名前> lt; /性別>
黒竜江省アドレス>
yuepengfei@mail.banner.com.cnメール>
166581208 7665
;sports98
機密
男性 <誕生日> メール>flyruns@hotmail>
15787767
11599322 >/スキル> ;
<ホームページ>http:// www.hiviresearch.com/cgi/report/
2002-1-5
;
次のコンテンツをresume1として保存します
履歴
モデレータ情報
gt;別名 |
gt;名前 |
性別 |
gt;所在地 |
gt ;
| gt;gt; |
gt;gt ; |
gt;gt; |
|
以下の内容はresume2.xsl
として保存されます。
人简历
頭>
版主情報
名前 | |
姓 |
性别 |
gt;所在地 |
gt;gt; |
|
;
追加時間 |
---|
专长 |
TD>
---|
ICQ |
< ;/TD>
---|
OICQ |
---|
主页 |
在ie5以上浏览器上查看resume.xml,并可修正resume.xml中 当然のことながら、すべてのブラウザがこの変換をサポートしているわけではないため、サーバー上で変換を行う必要があります。 php
require_once "xsl_class.php";
$xml = 新しいXML;
$p = 新しいXSL;
$p->parser("resume2.xsl",$xml->parser("resume.xml") );
$p->display();
?>
その中のresume2.xslを変更すると、HTML形式に変換されただけで、別の面が表示されます。 xml 文の解析は、domxml に似た構造を生成します
xsl_class は xml_class から派生し、xsl 文の解析と xsl 関数の模倣に使用されますが、その中のテンプレートはまだ実装されていません。
xml_class.php
*****************
class 要素 {
var $Element;
var $Text; // このようなポイントは、文書内の任意の要素に使用されます。要素ポイントの子ノードは、そのコンテンツの要素ポイント、注釈ポイント、処理情報ポイント、およびテキスト ブックの場合があります。 // テキスト内に表示されるすべてのテキスト、すべてのパケットがテキスト ポイントに挿入されます。テキスト ポイントは、テキスト ポイントの前後の兄弟ノードであることはできません。 // 各エレメント ポイントには、独自に追加されたプロパティ ポイントがあります。承認されたプロパティ値は、指定されたプロパティと同様の方法で処理されます。これらのポイントには子ノードがありません。 // xlmns: およびプロパティ ノードの各要素には、すべて 1 つの名前空間があります。これらのノードには子ノードがありません。 // 各処理命令にはそれぞれ個別のノードがあります。これらのノードには子ノードがありません。
var $parents = array(); // それぞれに 1 つの注釈ポイントがあります。これらのポイントには子ポイントがありません。
var $childs = array();
}
class xml {
var $tm = array();
var $xml_parser;
var $data = array();
var $element = "";
var $stack = array(); // 現在のヘッダーの関連パラメータをキャッシュします
var $type;
function trustedFile($file) {
// 自分が所有するローカル ファイルのみを信頼します
if (!eregi("^ ([a-z]+)://", $file)
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;
}
}
//要素の終了ヘッダ
関数の処理 endElement($parser, $name) {
$element = array_pop($this->stack);
if(is_array ($element)) {
$element[Element][] = $ This-& gt; 要素
} else {
$ThIS-> = $ This-& GT Element;
}
}
//文字データヘッダーの処理
function CharacterData($data) {
$data = eregi_replace("^ +","" ,$data);
$data = eregi_replace(" ^n+","",$data);
if(strlen($data) > 0) {
$this->element[Text] .= $data ;
}
}
//処理命令タグ Header
function PIHandler($parser, $target, $data) {
switch(strto lower($target)) {
case "php":
global $parser_file;
/ / 解析されたドキュメントが「信頼できる」場合、安全であると言えます
’ s } Else {
$ this-& gtm [] = sprintf ("信頼できない php コード: & lt; i & gt;%s & lt;/i & gt;",
htmlspecialchars ($ data)); ; デフォルト:
// echo $target;
// echo "==".$data;
// echo printf("%s %s",$target,$data); Break; デフォルトヘッダ
関数defaultHandler($parser, $data) {
if(substr($data, 0, 1) == "&" && substr($data, - 1, 1) == ";") {
$this->tm[] = sprintf('%s',
htmlspecialchars($data)) ;
}else {
[] = 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_par)サー, $data, feof($fp))) {
die(sprintf("XML エラー: %s 行 %dn",
xml_error_string(xml_get_error_code($xml_parser)),
x ml_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],コマンド => $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) {
// }
// デフォルトヘッダーを処理します
関数 defaultHandler($parser, $data) {
}
// 外部エンティティ参照ヘッダーを処理します
// 関数externalEntityRefHandler($parser, $openEntityNames, $base, $systemId, $publicId) {
// }
// XSL 命令解析
function xsl_parser($i) {
for(;$i [xsl]))
return $i;
デフォルトレベルの場合は $i を返します
$ps = join("/",$this->datastack)"/ $ps";
}
return "[$ps]";
}
// 結果を出力
function display () {
$this->stack = array(); // 制御スタックを初期化する
$this ->datastack = array(); //データスタックを初期化します
$type = true; //アイテムのテキスト出力を制御するために使用されます
for($id=0;$iddata) );$id++) {
$expr = $this->data[$id];
list($key,$ value) = each($expr);
switch($key) {
case "タグ": echo "&lt;"。$ value。 "&gt; ,$command) = each($expr); // 操作セットを取得します
$value = eregi_replace("eval","xsl_eval",$value); 開始ノード、$field ノード名、$n 回の一致
関数 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][名前])) {
フィールド。 "$"、$ root [$ i] [name])){
}
$ n))
be、array($ id、$ command [select]、1)); $command[SELECT]);
// データ ポインターがスタックにプッシュされます
array_push($this->datastack,$data);
}
function _for_each($command,&$id) {
// Getエントリアドレス
$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;
/ データ ポインターを取得します $data = $this->find($dsn,$ar[1],$n);
if($data) {
// 取得したらループします
$ ar[2] +; コマンド) {
= array_pop($this->datastack);
array_push($this->datastack,$dsn) ; $dsn,$command[SELECT]);
}
}
print $data[Text];
}
function _value_of() {
}
function stylesheet() {
}
function _stylesheet() {
}
function template( $command) {
echo join(" ",$ command)."
gt;";
}
function _template() {
}
function apply_templates($command) {
echo join(" ",$command) ."
";
}
function _apply_templates() {
}
関数 xsl_eval() {
}
関数 _xsl_eval() {
}
}
/****付録****
データ要素ノード
配列
(
[名前] // ノード名
[テキスト]
[属性]
[名前空間]
[コメント]
[処理命令]
[要素] =>配列()
)
*************/
?>
声明:この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。