2016-10-06 15:57:01 +00:00
|
|
|
|
<?php
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* 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
|
|
|
|
|
*
|
2019-07-03 11:58:28 +00:00
|
|
|
|
* $Id$:
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* }}
|
|
|
|
|
*
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
if (!defined('CON_FRAMEWORK')) {
|
|
|
|
|
die('Illegal call');
|
2016-10-06 15:57:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 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();
|
|
|
|
|
*
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
class XsltProcessor {
|
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* XSML Processor auto-free
|
|
|
|
|
* @var bool
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $autofree = true;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Error message string
|
|
|
|
|
* @var string
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $error = "";
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Error number
|
|
|
|
|
* @var int
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $errno = 0;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The result of the XSLT Transformation
|
|
|
|
|
* @var string
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $result = "";
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* The XML String for the Transformation
|
|
|
|
|
* @var string
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $xml = "";
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* The XSLT String for the Transformation
|
|
|
|
|
* @var string
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $xslt = "";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* XSLT Processor
|
|
|
|
|
* @var object
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $processor;
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* XSLT Process arguments array
|
|
|
|
|
* @var array
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $arguments = array();
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* XSLT Process parameters array
|
|
|
|
|
* @var array
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
|
|
|
|
var $parameters = array();
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
* @access private
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function __construct() {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$this->_init();
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Initialize the class
|
|
|
|
|
* @access private
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function _init() {
|
|
|
|
|
if (!function_exists("xslt_create")) {
|
|
|
|
|
die("Cannot instantiate XSLT Class \n XSLT not supported");
|
2016-10-06 15:57:01 +00:00
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$this->processor = xslt_create();
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Translate literal to numeric entities to avoid
|
|
|
|
|
* the 'undefined entity error' that a literal
|
|
|
|
|
* entity would cause.
|
2018-12-10 12:13:27 +00:00
|
|
|
|
*
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* @param string XML String with literal entities
|
|
|
|
|
* @return string XML string with numeric entites
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access private
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
|
|
|
|
function literal2NumericEntities($stringXml) {
|
|
|
|
|
|
|
|
|
|
$literal2NumericEntity = array();
|
|
|
|
|
|
2018-12-10 12:13:27 +00:00
|
|
|
|
if (empty($literal2NumericEntity)) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$transTbl = clGetHtmlTranslationTable(HTML_ENTITIES);
|
|
|
|
|
|
2018-12-10 12:13:27 +00:00
|
|
|
|
foreach ($transTbl as $char => $entity) {
|
|
|
|
|
if (strpos('&"<>', $char) !== FALSE)
|
|
|
|
|
continue;
|
|
|
|
|
$literal2NumericEntity[$entity] = '&#' . ord($char) . ';';
|
2016-10-06 15:57:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return strtr($stringXml, $literal2NumericEntity);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Set the XML to be Transformed
|
|
|
|
|
* @param string The XML String
|
|
|
|
|
* @return void
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function setXml($xml) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$this->arguments["/_xml"] = $this->literal2NumericEntities($xml);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Set the XSLT for the Transformation
|
|
|
|
|
* @param string The XML String
|
|
|
|
|
* @return void
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function setXsl($xsl) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$this->arguments["/_xsl"] = $this->literal2NumericEntities($xsl);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* Set the XML-File to be Transformed
|
|
|
|
|
* @param string Location of the XML file
|
|
|
|
|
* @return void
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function setXmlFile($file) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$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
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function setXslFile($file) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$xsl = $this->readFromFile($file);
|
|
|
|
|
$this->arguments["/_xsl"] = $this->literal2NumericEntities($xsl);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Return the contents of a file if
|
|
|
|
|
* the passed parameter is a file.
|
2018-12-10 12:13:27 +00:00
|
|
|
|
*
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* @param string File location
|
|
|
|
|
* @return string File contents
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access private
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function readFromFile($file) {
|
|
|
|
|
if (file_exists($file)) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$data = file($file);
|
|
|
|
|
$data = join($data, "");
|
|
|
|
|
return $data;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-10 12:13:27 +00:00
|
|
|
|
die("<span style=\"color: red\"><b>ERROR:</b></span> File not found: <b>$file</b>");
|
2016-10-06 15:57:01 +00:00
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Pass top level parameters to the XSLT processor.
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* The parameters can be accessed in XSL
|
|
|
|
|
* with <xsl:param name="paramname"/>
|
|
|
|
|
*
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* @param string Name
|
|
|
|
|
* @param string Value
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function setParam($name, $value) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$this->parameters[$name] = utf8_encode($value);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* 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);
|
|
|
|
|
}
|
2016-10-06 15:57:01 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Transform the XML data using the XSL and
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* return the results of the transformation
|
|
|
|
|
*
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* @return string Transformed data
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function process() {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
$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);
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
|
|
|
|
if ($this->autofree) {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
xslt_free($this->processor);
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
return $this->result;
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Prints the Error message and number
|
|
|
|
|
* if an error occured
|
2018-12-10 12:13:27 +00:00
|
|
|
|
*
|
2016-10-06 15:57:01 +00:00
|
|
|
|
* @return void
|
2018-12-10 12:13:27 +00:00
|
|
|
|
* @access public
|
2016-10-06 15:57:01 +00:00
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
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>";
|
2016-10-06 15:57:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-12-10 12:13:27 +00:00
|
|
|
|
|
2016-10-06 15:57:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Manual free of the parser
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2018-12-10 12:13:27 +00:00
|
|
|
|
function free() {
|
2016-10-06 15:57:01 +00:00
|
|
|
|
xslt_free($this->processor);
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-10 12:13:27 +00:00
|
|
|
|
}
|