ConLite/conlite/classes/class.xsltprocessor.php

319 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
*
2019-07-03 11:58:28 +00:00
* $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("<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);
}
}