“Click to activate and use this control”
Sep 18

Próbowałeś kiedyś wstawić w XSL kod JavaScript? Problem polega na tym, że po zamknięciu kodu JS w tagi <script></script> i przepuszczeniu takiego XSL-a przez procesor XSL zainstalowany domyślnie w PHP5, Twoj kod JavaScript zostanie zamknięty w znaczniki <![CDATA[ ]]>, co spowoduje wyświetlenie błędu JavaScript oraz chęć uderzenia w klawiaturę. Jeżeli masz wystarczająco dużo cierpliwości i wytrzymałą klawiaturę dojdziesz do wniosku, że należy zastosować trik w postaci “wstrzyknięcia” znaczników <script> za pomocą XSL do HTMLa wynikowego.

Ja zrobiłem to tak:

<?php
// Do zmiennej wpisuję testowego XMLa
$xmlString = ‘<xml><alert>To powinno wyświetlić mi się w alercie</alert></xml>’;

// Do drugiej zmiennej wpisuję XSLa
$xslString = ‘<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" omit-xml-declaration="yes" indent="no"/>
<xsl:template match="xml"><html><body>

<!– dupa… błąd JS –>
<script type="text/javascript">
alert("<xsl:value-of select="alert"/>");
</script>

<!– działa! szczęście rodziny, pokój na świecie –>
<xsl:text disable-output-escaping="yes">&lt;script type="text/javascript"&gt;</xsl:text>
alert("<xsl:value-of disable-output-escaping="yes" select="alert"/>");
<xsl:text disable-output-escaping="yes">&lt;/script&gt;</xsl:text>

</body></html></xsl:template>
</xsl:stylesheet>’;

// Przekształcam wszystko na HTMLa ..
$xml = new DOMDocument();
$xsl = new XSLTProcessor();
$xml->loadXML($xslString);
$xsl->importStyleSheet($xml);
$xml->loadXML($xmlString);

// .. i wyświetlam
print($xsl->transformToXML($xml));
?>

Na pewno da się ten problem rozwiązać na kilka sposobów, np kompilując php z opcją:
php –without-idiotycznecdatapotaguscript
zmieniając wartość atrybutu:
$xsl->wstawMnieWKodKretynskieCdata = FALSE;
lub importując xsla do procesora z jakąś czarodziejską stałą
$xml->loadXML($xslString, NO_FCKIN_CDATA_PLIS);

lecz jeżeli nie masz możliwości zmienienia konfiguracji php, masz za mało czasu i jedną klawiaturę, to powyższe rozwiązanie może być przydatne.

Skomentuj