[ Index ] |
|
Code source de Symfony 1.0.0 |
1 <?php 2 3 /* 4 * $Id: XsltFilter.php 3076 2006-12-18 08:52:12Z fabien $ 5 * 6 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 7 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 8 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 9 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 10 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 11 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 13 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 14 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 15 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 16 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 * 18 * This software consists of voluntary contributions made by many individuals 19 * and is licensed under the LGPL. For more information please see 20 * <http://phing.info>. 21 */ 22 23 include_once 'phing/filters/BaseParamFilterReader.php'; 24 include_once 'phing/filters/ChainableReader.php'; 25 26 /** 27 * Applies XSL stylesheet to incoming text. 28 * 29 * Uses PHP XSLT support (libxslt). 30 * 31 * @author Hans Lellelid <hans@velum.net> 32 * @author Yannick Lecaillez <yl@seasonfive.com> 33 * @author Andreas Aderhold <andi@binarycloud.com> 34 * @version $Revision: 1.16 $ 35 * @see FilterReader 36 * @package phing.filters 37 */ 38 class XsltFilter extends BaseParamFilterReader implements ChainableReader { 39 40 /** 41 * Path to XSL stylesheet. 42 * @var string 43 */ 44 private $xslFile = null; 45 46 /** 47 * Whether XML file has been transformed. 48 * @var boolean 49 */ 50 private $processed = false; 51 52 /** 53 * XSLT Params. 54 * @var array 55 */ 56 private $xsltParams = array(); 57 58 /** 59 * Whether to use loadHTML() to parse the input XML file. 60 */ 61 private $html = false; 62 63 /** 64 * Create new XSLT Param object, to handle the <param/> nested element. 65 * @return XSLTParam 66 */ 67 function createParam() { 68 $num = array_push($this->xsltParams, new XSLTParam()); 69 return $this->xsltParams[$num-1]; 70 } 71 72 /** 73 * Sets the XSLT params for this class. 74 * This is used to "clone" this class, in the chain() method. 75 * @param array $params 76 */ 77 function setParams($params) { 78 $this->xsltParams = $params; 79 } 80 81 /** 82 * Returns the XSLT params set for this class. 83 * This is used to "clone" this class, in the chain() method. 84 * @return array 85 */ 86 function getParams() { 87 return $this->xsltParams; 88 } 89 90 /** 91 * Set the XSLT stylesheet. 92 * @param mixed $file PhingFile object or path. 93 */ 94 function setStyle(PhingFile $file) { 95 $this->xslFile = $file; 96 } 97 98 /** 99 * Whether to use HTML parser for the XML. 100 * This is supported in libxml2 -- Yay! 101 * @return boolean 102 */ 103 function getHtml() { 104 return $this->html; 105 } 106 107 /** 108 * Whether to use HTML parser for XML. 109 * @param boolean $b 110 */ 111 function setHtml($b) { 112 $this->html = (boolean) $b; 113 } 114 115 /** 116 * Get the path to XSLT stylesheet. 117 * @return mixed XSLT stylesheet path. 118 */ 119 function getStyle() { 120 return $this->xslFile; 121 } 122 123 /** 124 * Reads stream, applies XSLT and returns resulting stream. 125 * @return string transformed buffer. 126 * @throws BuildException - if XSLT support missing, if error in xslt processing 127 */ 128 function read($len = null) { 129 130 if (!class_exists('XSLTProcessor')) { 131 throw new BuildException("Could not find the XSLTProcessor class. Make sure PHP has been compiled/configured to support XSLT."); 132 } 133 134 if ($this->processed === true) { 135 return -1; // EOF 136 } 137 138 if ( !$this->getInitialized() ) { 139 $this->_initialize(); 140 $this->setInitialized(true); 141 } 142 143 // Read XML 144 $_xml = null; 145 while ( ($data = $this->in->read($len)) !== -1 ) 146 $_xml .= $data; 147 148 if ($_xml === null ) { // EOF? 149 return -1; 150 } 151 152 if(empty($_xml)) { 153 $this->log("XML file is empty!", PROJECT_MSG_WARN); 154 return ''; // return empty string, don't attempt to apply XSLT 155 } 156 157 // Read XSLT 158 $_xsl = null; 159 $xslFr = new FileReader($this->xslFile); 160 $xslFr->readInto($_xsl); 161 162 $this->log("Tranforming XML " . $this->in->getResource() . " using style " . $this->xslFile->getPath(), PROJECT_MSG_VERBOSE); 163 164 $out = ''; 165 try { 166 $out = $this->process($_xml, $_xsl); 167 $this->processed = true; 168 } catch (IOException $e) { 169 throw new BuildException($e); 170 } 171 172 return $out; 173 } 174 175 // {{{ method _ProcessXsltTransformation($xml, $xslt) throws BuildException 176 /** 177 * Try to process the XSLT transformation 178 * 179 * @param string XML to process. 180 * @param string XSLT sheet to use for the processing. 181 * 182 * @throws BuildException On XSLT errors 183 */ 184 protected function process($xml, $xsl) { 185 186 $processor = new XSLTProcessor(); 187 188 $xmlDom = new DOMDocument(); 189 $xslDom = new DOMDocument(); 190 191 if ($this->html) { 192 $xmlDom->loadHTML($xml); 193 } else { 194 $xmlDom->loadXML($xml); 195 } 196 197 $xslDom->loadxml($xsl); 198 199 $processor->importStylesheet($xslDom); 200 201 // ignoring param "type" attrib, because 202 // we're only supporting direct XSL params right now 203 foreach($this->xsltParams as $param) { 204 $this->log("Setting XSLT param: " . $param->getName() . "=>" . $param->getExpression(), PROJECT_MSG_DEBUG); 205 $processor->setParameter(null, $param->getName(), $param->getExpression()); 206 } 207 208 $result = $processor->transformToXML($xmlDom); 209 210 if ( !$result ) { 211 //$errno = xslt_errno($processor); 212 //$err = xslt_error($processor); 213 throw new BuildException("XSLT Error"); 214 } else { 215 return $result; 216 } 217 } 218 219 /** 220 * Creates a new XsltFilter using the passed in 221 * Reader for instantiation. 222 * 223 * @param Reader A Reader object providing the underlying stream. 224 * Must not be <code>null</code>. 225 * 226 * @return Reader A new filter based on this configuration, but filtering 227 * the specified reader 228 */ 229 function chain(Reader $reader) { 230 $newFilter = new XsltFilter($reader); 231 $newFilter->setProject($this->getProject()); 232 $newFilter->setStyle($this->getStyle()); 233 $newFilter->setInitialized(true); 234 $newFilter->setParams($this->getParams()); 235 $newFilter->setHtml($this->getHtml()); 236 return $newFilter; 237 } 238 239 /** 240 * Parses the parameters to get stylesheet path. 241 */ 242 private function _initialize() { 243 $params = $this->getParameters(); 244 if ( $params !== null ) { 245 for($i = 0, $_i=count($params) ; $i < $_i; $i++) { 246 if ( $params[$i]->getType() === null ) { 247 if ($params[$i]->getName() === "style") { 248 $this->setStyle($params[$i]->getValue()); 249 } 250 } elseif ($params[$i]->getType() == "param") { 251 $xp = new XSLTParam(); 252 $xp->setName($params[$i]->getName()); 253 $xp->setExpression($params[$i]->getValue()); 254 $this->xsltParams[] = $xp; 255 } 256 } 257 } 258 } 259 260 } 261 262 263 /** 264 * Class that holds an XSLT parameter. 265 */ 266 class XSLTParam { 267 268 private $name; 269 270 private $expr; 271 272 /** 273 * Sets param name. 274 * @param string $name 275 */ 276 public function setName($name) { 277 $this->name = $name; 278 } 279 280 /** 281 * Get param name. 282 * @return string 283 */ 284 public function getName() { 285 return $this->name; 286 } 287 288 /** 289 * Sets expression value. 290 * @param string $expr 291 */ 292 public function setExpression($expr) { 293 $this->expr = $expr; 294 } 295 296 /** 297 * Sets expression to dynamic register slot. 298 * @param RegisterSlot $expr 299 */ 300 public function setListeningExpression(RegisterSlot $expr) { 301 $this->expr = $expr; 302 } 303 304 /** 305 * Returns expression value -- performs lookup if expr is registerslot. 306 * @return string 307 */ 308 public function getExpression() { 309 if ($this->expr instanceof RegisterSlot) { 310 return $this->expr->getValue(); 311 } else { 312 return $this->expr; 313 } 314 } 315 } 316 317 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |