jump to navigation

Render XML with XSLT (XsltView) (updated) June 3, 2006

Posted by rossoft in CakePHP.
trackback

Render XML with XSLT.
The xml can be a file in views/controller_name/action.xml (will be rendered like .thtml files, you can put php code in it)
or a view-variable (in the controller: $this->set(’xml’,$xml_string); )
Same for xsl, views/controller_name/action.xsl or $this->set(’xsl’,$xsl_string);

Examples: put those actions in your controller:
Example1:
//xsl through views/controller_name/action.xsl file, xml through view-variable

function example1()
{
$this->view='Xslt';
$xml='
<expenses>
<item date="2004-11-03">
<desc>Lavado completo</desc>
<location>Barcelona, Spain</location>
<amount currencyCode="EUR">50.45</amount>
</item>

<item date="2004-11-04">
<desc>Comida</desc>
<location>Londres, Inglaterra</location>
<amount currencyCode="GBP">35.2</amount>
</item>
</expenses>';
$this->set('xml',$xml);
}

Example2:
//xsl through views/controller_name/action.xsl file, xml through views/controller_name/action.xml file

function example2()
{
$this->view=’Xslt’;
}

Copy this to app/views/xslt.php:

<?php
/**
 * Xslt View
 * Renders XML with XSLT.
 *
 * The xml can be a file in views/controller_name/action.xml (will be rendered like .thtml files, you can put php code in it)
 * or a view-variable (in the controller: $this->set('xml',$xml_string); )
 * Same for xsl, views/controller_name/action.xsl or $this->set('xsl',$xsl_string);
 *
 * @author RosSoft
 * @version 0.11
 * @license MIT
 *
 * @link http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/
 */
class XsltView extends View
{
    function render($action = null, $layout = null, $file = null)
    {
        header('Content-Type: text/xml');
        $this->autoLayout=false;
        $file=null;       

        if ($action==NULL)
        {
            $action=$this->action;
        }       

        if (!isset($this->_viewVars['xml']))
        {
            $file=$this->get_filename($action,'.xml');
            ob_start();
            parent::render($action,$layout,$file);
            $xml=ob_get_clean();                       
        }
        else
        {
            $xml=$this->_viewVars['xml'];
        }

        $this->hasRendered=false;
        if (!isset($this->_viewVars['xsl']))
        {       
            $file=$this->get_filename($action,'.xsl');
            ob_start();       
            parent::render($action,$layout,$file);
            $xsl=ob_get_clean();
        }                       
        else
        {
            $xsl=$this->_viewVars['xsl'];
        }
       
        $xh = xslt_create();
        $args=array('xml'=>$xml,'xsl'=>$xsl);
       
        $result=xslt_process($xh, 'arg:xml','arg:xsl',null,$args );
        echo $result;
    }
   
    /**
     * Returns the filename associated with the action
     * with the extension ".$ext"
     *
     * @param string $action If null, then current action
     * @param string $ext Extension of the view template (with dot) Example: '.xml'
     * @return string
     */
    function get_filename($action,$ext)
    {       
        $old_ext=$this->ext;
        $this->ext=$ext;
        $fn=$this->_getViewFileName($action);
        $this->ext=$old_ext;
        return $fn;
    }
}      

/**
 * PHP4-5 Compatibility
 * @link http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/index.en.html
 */
if (version_compare(PHP_VERSION,'5','>=')&&extension_loaded('xsl'))
{
    /*
     Requires PHP5, uses included XSL extension (to be enabled).
     To be used in PHP4 scripts using XSLT extension.
     Allows PHP4/XSLT scripts to run on PHP5/XSL
   
     Typical use:
     {
      if (version_compare(PHP_VERSION,'5','>=')&&extension_loaded('xsl'))
       require_once('xslt-php4-to-php5.php');
     }
   
     Version 0.4, 2005-08-28, http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/
   
     ——————————————————————
     Written by Alexandre Alapetite, http://alexandre.alapetite.net/cv/
   
    Copyright 2004-2005, Licence: Creative Commons "Attribution-ShareAlike 2.0 France" BY-SA (FR),
     http://creativecommons.org/licenses/by-sa/2.0/fr/
     http://alexandre.alapetite.net/divers/apropos/#by-sa
     – Attribution. You must give the original author credit
     – Share Alike. If you alter, transform, or build upon this work,
       you may distribute the resulting work only under a license identical to this one
     – The French law is authoritative
     – Any of these conditions can be waived if you get permission from Alexandre Alapetite
     – Please send to Alexandre Alapetite the modifications you make,
       in order to improve this file for the benefit of everybody
   
     If you want to distribute this code, please do it as a link to:
     http://alexandre.alapetite.net/doc-alex/xslt-php4-php5/
    */
   
    $xslArgs=null;
    function xslt_create() {return new xsltprocessor();}
    function xslt_free($xh) {unset($xh);}
    function xslt_errno($xh) {return 7;}
    function xslt_error($xh) {return '?';}
    function xslt_process($xh,$xmlcontainer,$xslcontainer,$resultcontainer=null,$arguments=array(),$parameters=array())
    {//See also: http://alexandre.alapetite.net/doc-alex/domxml-php4-php5/
     //Based on: http://www.php.net/manual/ref.xsl.php#45415
     $xml=new DOMDocument();
     $basedir=$xh->getParameter('sablotron','xslt_base_dir');
     if ($basedir && ($workdir=getcwd()))
      chdir($basedir);
     if (substr($xmlcontainer,0,4)=='arg:')
      $xml->loadXML($arguments[substr($xmlcontainer,4)]);
     else $xml->load($xmlcontainer);
     $xsl=new DOMDocument();
     if (substr($xslcontainer,0,4)=='arg:')
      $xsl_=&$arguments[substr($xslcontainer,4)];
     else $xsl_=file_get_contents($xslcontainer);
     $xsl->loadXML(str_replace('arg:/','arg://',$xsl_));
     $xh->importStyleSheet($xsl);
     global $xslArgs;
     $xslArgs=$arguments;
     foreach ($parameters as $param=>$value)
      $xh->setParameter('',$param,$value);
     $result=$xh->transformToXML($xml);
     if (isset($resultcontainer))
      file_put_contents($resultcontainer,$result);
     if ($basedir && $workdir)
      chdir($workdir);
     if (isset($resultcontainer))
      return true;
     else return $result;
    }
    function xslt_set_base($xh,$base) {$xh->setParameter('sablotron','xslt_base_dir',str_replace('file://','',$base));}
    function xslt_set_error_handler($xh,$handler) {};
   
    class xslt_arg_stream
    {
     var $position;
     var $xslArg;
     function stream_eof() {return $this->position>=strlen($this->xslArg);}
     function stream_open($path,$mode,$options,&$opened_path)
     {
      $this->position=0;
      $url=parse_url($path);
      $varname=$url['host'];
      global $xslArgs;
      if (isset($xslArgs['/'.$varname]))
       $this->xslArg=&$xslArgs['/'.$varname];
      elseif (isset($xslArgs[$varname]))
       $this->xslArg=&$xslArgs[$varname];
      else return false;
      return true;
     }
     function stream_read($count)
     {
      $ret=substr($this->xslArg,$this->position,$count);
      $this->position+=strlen($ret);
      return $ret;
     }
     function stream_tell() {return $this->position;}
     function url_stat() {return array();}
    }
   
    stream_wrapper_register('arg','xslt_arg_stream');
}

?>

Advertisements

Comments»

1. rossoft - June 13, 2006

function __construct (&$controller)
{
parent::__construct($controller);
}

is useless, remove it

2. dts - June 19, 2006

I am receiving error while using return new XsltProcessor(). please help

3. rossoft - June 19, 2006

do you have the xslt extension?

4. rossoft - June 19, 2006

I’ve updated it for bug fix


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: