339 Zeilen
7,5 KiB
PHP
339 Zeilen
7,5 KiB
PHP
<?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
|
||
|
||
?>
|