1<?php 2/** 3 * Plugin XSLT : Perform XSL Transformation on provided XML data 4 * 5 * To be run with Dokuwiki only 6 * 7 * Sample data provided at the end of the file 8 * 9 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 10 * @author R�mi Peyronnet <remi+xslt@via.ecp.fr> 11 */ 12 13if(!defined('DOKU_INC')) die(); 14if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 15require_once(DOKU_PLUGIN.'syntax.php'); 16 17class syntax_plugin_xslt extends DokuWiki_Syntax_Plugin { 18 19 function getInfo(){ 20 return array( 21 'author' => 'R�mi Peyronnet', 22 'email' => 'remi+xslt@via.ecp.fr', 23 'date' => '2009-03-07', 24 'name' => 'XSLT Plugin', 25 'desc' => 'Perform XSL Transformation on provided XML data', 26 'url' => 'http://people.via.ecp.fr/~remi/', 27 ); 28 } 29 30 function getType() { return 'substition'; } 31 function getPType() { return 'block'; } 32 function getSort() { return 1242; } 33 function connectTo($mode) { $this->Lexer->addSpecialPattern('&&XML&&\n.*\n&&XSLT&&\n.*\n&&END&&',$mode,'plugin_xslt'); } 34 35 function handle($match, $state, $pos, Doku_Handler $handler) 36 { 37 switch ($state) { 38 case DOKU_LEXER_SPECIAL : 39 $matches = preg_split('/(&&XML&&\n*|\n*&&XSLT&&\n*|\n*&&END&&)/', $match, 5); 40 $data = "XML: " . $matches[1] . "\nXSLT: ". $matches[2] . "(" . $match . ")"; 41 $xsltproc = new XsltProcessor(); 42 $xml = new DomDocument; 43 $xsl = new DomDocument; 44 $xml->loadXML($matches[1]); 45 $xsl->loadXML($matches[2]); 46 $xsltproc->registerPHPFunctions(); 47 $xsltproc->importStyleSheet($xsl); 48 $data = $xsltproc->transformToXML($xml); 49 50 if (!$data) { 51 $errors = libxml_get_errors(); 52 foreach ($errors as $error) { 53 $data = display_xml_error($error, $xml); 54 } 55 libxml_clear_errors(); 56 } 57 58 unset($xsltproc); 59 return array($state, $data); 60 61 case DOKU_LEXER_UNMATCHED : return array($state, $match); 62 case DOKU_LEXER_EXIT : return array($state, ''); 63 } 64 return array(); 65 } 66 67 function render($mode, Doku_Renderer $renderer, $data) 68 { 69 if($mode == 'xhtml'){ 70 list($state, $match) = $data; 71 switch ($state) { 72 case DOKU_LEXER_SPECIAL : 73 $renderer->doc .= $match; 74 break; 75 76 case DOKU_LEXER_UNMATCHED : $renderer->doc .= $renderer->_xmlEntities($match); break; 77 case DOKU_LEXER_EXIT : $renderer->doc .= ""; break; 78 } 79 return true; 80 } 81 return false; 82 } 83} 84 85 86function display_xml_error($error, $xml) 87{ 88 $return = $xml[$error->line - 1] . "\n"; 89 $return .= str_repeat('-', $error->column) . "^\n"; 90 91 switch ($error->level) { 92 case LIBXML_ERR_WARNING: 93 $return .= "Warning $error->code: "; 94 break; 95 case LIBXML_ERR_ERROR: 96 $return .= "Error $error->code: "; 97 break; 98 case LIBXML_ERR_FATAL: 99 $return .= "Fatal Error $error->code: "; 100 break; 101 } 102 103 $return .= trim($error->message) . 104 "\n Line: $error->line" . 105 "\n Column: $error->column"; 106 107 if ($error->file) { 108 $return .= "\n File: $error->file"; 109 } 110 111 return "$return\n\n--------------------------------------------\n\n"; 112} 113 114/* 115 116Sample data : 117 118This is my list of books, maintained in XML/XSLT inside Dokuwiki. 119&&XML&& 120 121<xml> 122<book>Book 1</book> 123<book>Book 2</book> 124</xml> 125 126&&XSLT&& 127 128<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/REC-html40"> 129<xsl:template match="/">List of books : <ul><xsl:apply-templates /></ul></xsl:template> 130<xsl:template match="book"><li><b><xsl:apply-templates /></b></li></xsl:template> 131</xsl:stylesheet> 132 133&&END&& 134 135 136*/ 137 138?>