ConLite/conlite/classes/class.xsltprocessor.php

340 Zeilen
7.5 KiB
PHP
Originalformat Blame Verlauf

<?php
/**
* Project:
* Contenido Content Management System
*
* Description:
* XSLT_Processor class
*
* Requirements:
* @con_php_req 5.0
*
*
* @package Contenido_XML
* @version 1.0.0
* @author Jan Lengowski
* @copyright four for business AG <www.4fb.de>
* @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: class.xsltprocessor.php 374 2015-11-09 15:59:28Z oldperl $:
* }}
*
*/
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 XsltProcessor()
{
$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 ("<span style=\"color: red\"><b>ERROR:</b></span> File not found: <b>$file</b>");
}
/**
* Pass top level parameters to the XSLT processor.
* The parameters can be accessed in XSL
* with <xsl:param name="paramname"/>
*
* @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 '<?xml version="1.0" encoding="UTF-8"?><root>'.(file_exists($param) ? "true" : "false")."</root>";
* }
* }
*
* To use the schema handler use:
* <xsl:if test="document('file_exists:somefile.xml<6D>)/root = 'true'">
* do something
* </xsl:if>
*
* To call the external function use the 'document()' XSLT-Function.
*
* <xsl:value-of select="document('schemename:parameter')/root"/>
*
* 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 "<b>Error Number: </b><span style=\"color:red\">".$this->errno."</span> ";
echo "<b>Error Message: </b><span style=\"color:red\">".$this->error."</span>";
}
}
/**
* Manual free of the parser
* @return void
*/
function free()
{
xslt_free($this->processor);
}
} // XSLT_Processor
?>