* @license http://www.contenido.org/license/LIZENZ.txt * @link http://www.4fb.de * @link http://www.contenido.org * @since file available since contenido release <= 4.6 * * {@internal * created unknown * modified 2008-06-30, Dominik Ziegler, add security fix * * $Id$: * }} * */ if (!defined('CON_FRAMEWORK')) { die('Illegal call'); } /** * XSLT_Processor * * Wrapper class for the Sablotron XSLT extension * * !!! _REQUIRES_ Installed Sablotron to run !!! * * Example: * * $xslt = new XSLT_Processor; * * $xslt->setXmlFile("foo.xml"); * $xslt->setXslFile("bar.xslt"); * * $html = $xslt->process(); * */ class XsltProcessor { /** * XSML Processor auto-free * @var bool * @access private */ var $autofree = true; /** * Error message string * @var string * @access private */ var $error = ""; /** * Error number * @var int * @access private */ var $errno = 0; /** * The result of the XSLT Transformation * @var string * @access private */ var $result = ""; /** * The XML String for the Transformation * @var string * @access private */ var $xml = ""; /** * The XSLT String for the Transformation * @var string * @access private */ var $xslt = ""; /** * XSLT Processor * @var object * @access private */ var $processor; /** * XSLT Process arguments array * @var array * @access private */ var $arguments = array(); /** * XSLT Process parameters array * @var array * @access private */ var $parameters = array(); /** * Constructor * @access private */ function __construct() { $this->_init(); } /** * Initialize the class * @access private * @return void */ function _init() { if (!function_exists("xslt_create")) { die("Cannot instantiate XSLT Class \n XSLT not supported"); } $this->processor = xslt_create(); } /** * Translate literal to numeric entities to avoid * the 'undefined entity error' that a literal * entity would cause. * * @param string XML String with literal entities * @return string XML string with numeric entites * @access private */ function literal2NumericEntities($stringXml) { $literal2NumericEntity = array(); if (empty($literal2NumericEntity)) { $transTbl = clGetHtmlTranslationTable(HTML_ENTITIES); foreach ($transTbl as $char => $entity) { if (strpos('&"<>', $char) !== FALSE) continue; $literal2NumericEntity[$entity] = '&#' . ord($char) . ';'; } } return strtr($stringXml, $literal2NumericEntity); } /** * Set the XML to be Transformed * @param string The XML String * @return void * @access public */ function setXml($xml) { $this->arguments["/_xml"] = $this->literal2NumericEntities($xml); } /** * Set the XSLT for the Transformation * @param string The XML String * @return void * @access public */ function setXsl($xsl) { $this->arguments["/_xsl"] = $this->literal2NumericEntities($xsl); } /** * Set the XML-File to be Transformed * @param string Location of the XML file * @return void * @access public */ function setXmlFile($file) { $xml = $this->readFromFile($file); $this->arguments["/_xml"] = $this->literal2NumericEntities($xml); } /** * Set the XSL-File for the Transformation * @param string Location of the XSL file * @return void * @access public */ function setXslFile($file) { $xsl = $this->readFromFile($file); $this->arguments["/_xsl"] = $this->literal2NumericEntities($xsl); } /** * Return the contents of a file if * the passed parameter is a file. * * @param string File location * @return string File contents * @access private */ function readFromFile($file) { if (file_exists($file)) { $data = file($file); $data = join($data, ""); return $data; } die("ERROR: File not found: $file"); } /** * Pass top level parameters to the XSLT processor. * The parameters can be accessed in XSL * with * * @param string Name * @param string Value * @return void */ function setParam($name, $value) { $this->parameters[$name] = utf8_encode($value); } /** * Define external scheme handlers for the XSLT Processor. * * Example param array: * * array("get_all", "mySchemeHandler") * * Example scheme handler function: * * function mySchemeHandler($processor, $scheme, $param) * { * // to remove the first slash added by Sablotron * $param = substr($param, 1); * * if ($scheme == 'file_exists') * { // result is returned as valid xml string * return ''.(file_exists($param) ? "true" : "false").""; * } * } * * To use the schema handler use: * * do something * * * To call the external function use the 'document()' XSLT-Function. * * * * Schemename and parameter will be passed to the handler function as second and third parameter. * The return value of the function must be valid XML to access it using XPath. * * @param array array("scheme"=>"schemeHandlerName"); * @return void * @access public */ function setSchemeHandlers($aHandlers) { xslt_set_scheme_handlers($this->processor, $aHandlers); } /** * Transform the XML data using the XSL and * return the results of the transformation * * @return string Transformed data * @access public */ function process() { $this->result = xslt_process($this->processor, "arg:/_xml", "arg:/_xsl", NULL, $this->arguments, $this->parameters); $this->error = xslt_error($this->processor); $this->errno = xslt_errno($this->processor); if ($this->autofree) { xslt_free($this->processor); } return $this->result; } /** * Prints the Error message and number * if an error occured * * @return void * @access public */ function printErrors() { if ($this->errno > 0) { echo "Error Number: " . $this->errno . " "; echo "Error Message: " . $this->error . ""; } } /** * Manual free of the parser * @return void */ function free() { xslt_free($this->processor); } }