Script negli XSL

Vi sarà capitato, se lavorate con i file XSL, di voler incrementare le variabili.

Cominciamo subito con il dire che il valore di una variabile non è...variabile (perchè le avranno chiamate xsl:variable e non xsl:constant rimane, per me, un mistero).

In realtà, come in tutti gli ambiti informatici, ci sono dei workaround per raggiungere il risultato (ne cito due, uno dei quali è di mio fresco apprendimento):

  • Usare i template (questo è un workaround davvero e potrebbe non fare al caso vostro nel 75% dei casi)
  • Usare gli script xsl (tag msxsl:script), questo funziona invece nel 99% dei casi, vedrete dove si nasconde quell'1% (guardacaso io ci sono dentro )

Perchè i template potrebbero non fare al caso vostro?
Beh...potrei sbagliarmi e sfuggermi qualcosa, ma davvero non capisco come un template che incrementi una variabile, possa servire ad incrementare una variabile CONTINUAMENTE magari all'interno di un ciclo.

Se poi si include che il template risponde più alla definizione di Procedura che non a quella di Funzione (per chi fosse a digiuno di definizioni diciamo che è la stessa differenza che passa tra una Sub e una Function in VB.Net )...

Ma veniamo alla parte più interessante: il tag msxsl:script.

Per utilizzarlo occorre prima dichiarare che utilizzeremo il suo namespace (msxsl) in questo modo:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt">

Ora siamo liberi di scrivere il nostro script, nel linguaggio che vogliamo:

<msxsl:script language="JScript" implements-prefix="user">
var indice=0;

function Incrementa()
{
    indice=indice+1;
    return indice;
}
</msxsl:script>

Io solitamente inserisco questo tag sotto quello di apertura (xsl:stylesheet) ma prima di quello di template (xsl:template), non ho provato ad inserirlo all'interno del template, ma non credo sia comunque logicamente corretto.

Avrete notato che a questo punto però ho utilizzato anche un altro namespace: lo "user", e allora ci tocca dichiararlo nell'apertura che quindi diventa:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="http://miodominio.com/miosito">

Ora: come utilizzare questa funzione dal nostro XSL?

Beh...niente di più facile: basta un bel tag xsl:value-of:

    <xsl:value-of select="user:Incrementa()"/>

Dato che la variabile (questa volta davvero Variabile) viene inizializzata una volta al valore 0 e poi incrementata, tutte le volte otterremo il suo valore incrementato (stile contatore).

Ovvio che questo trucco può servire ad inserire altre, e più interessanti, funzioni...

Come dite?
Ah...a cosa si riferisce quell'1%?

Beh...al fatto che Sharepoint, che "ben"  si integra con tecnologie XML e .Net, purtoppo blocca il fantastico tag msxsl:script...

Quindi...buon divertimento per chi sviluppa su web "libero"...

powered by IMHO 1.3

Print | posted on lunedì 3 aprile 2006 15.24

Feedback

# re: Script negli XSL

Left by Massimo Gentilini at 03/04/2006 19.14
Gravatar Attenzione attenzione attenzione: se usate XslTransform della classe .Net 1.1 c'è un memory leak determinato dall'uso della Evidence.

Probabilmente SharePoint non fa usare gli script per quello. Le nuove classi del FW 2.0 hanno deprecato la classe XslTransform ma soffrono dello stesso problema visto che di default non consentono di fare script che necessitino della evidence stessa.

Saluti
Massimo

# re: Script negli XSL

Left by Francesco at 26/09/2006 17.41
Gravatar Abbiamo cercato di sfruttare il suo consiglio nel nostro codice ma abbiamo un errore da XMLSpy: Error in Xpath 2.0 expression Unknown function - Name and number of arguments do not match any function signature in the static context - 'urn:az-scripts:Incrementa'

Ecco il codice:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:az="urn:az-scripts">
<msxsl:script language="JScript" implements-prefix="az">
var spo=0;
function Incrementa()
{
spo=spo+430;
return spo;
}
</msxsl:script>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="sez" select="count(results/snapshot[@number=1]/sezione)"></xsl:variable>
<xsl:template match="/">
<X3D profile="Immersive" version="3.0">
<Scene>
<xsl:if test="$sez &gt; 0">
<xsl:for-each select="results/snapshot[@number=1]/sezione">
<xsl:apply-templates select="//sezione" />
</xsl:for-each>
</xsl:if>
</Scene>
</X3D>
</xsl:template>
<xsl:template match="sezione">
<Transform DEF="Piano_Stradale">
<xsl:attribute name="translation">0 0 <xsl:value-of select="az:Incrementa()" /></xsl:attribute>
<Viewpoint DEF="GenericoA" description="GenericoA" jump="true" fieldOfView="0.785" position="40 50 -200" orientation="-0 .977 .215 2.994"/>
<Viewpoint DEF="GenericoB" description="GenericoB" jump="true" fieldOfView="0.785" position="40 50 200" orientation="-.804 .588 .085 .443"/>
<Transform DEF="dad_Viste_Laterali" translation="15 0 0" rotation="0 0 1 .524">
<Viewpoint DEF="A1" containerField="children" description="A1" jump="true" fieldOfView="0.785" position="75 0 172" orientation="0 1 0 1.571"/>
<Viewpoint DEF="A2" containerField="children" description="A2" jump="true" fieldOfView="0.785" position="75 0 86" orientation="0 1 0 1.571"/>
<Viewpoint DEF="A3" containerField="children" description="A3" jump="true" fieldOfView="0.785" position="75 0 0" orientation="0 1 0 1.571"/>
<Viewpoint DEF="A4" containerField="children" description="A4" jump="true" fieldOfView="0.785" position="75 0 -86" orientation="0 1 0 1.571"/>
<Viewpoint DEF="A5" containerField="children" description="A5" jump="true" fieldOfView="0.785" position="75 0 -172" orientation="0 1 0 1.571"/>
</Transform>
<Viewpoint DEF="Alto1" description="Alto1" jump="true" fieldOfView="0.785" position="0 200 130" orientation="-1 0 0 1.571"/>
<Viewpoint DEF="Alto2" description="Alto2" jump="true" fieldOfView="0.785" position="0 200 0" orientation="-1 0 0 1.571"/>
<Viewpoint DEF="Alto3" description="Alto3" jump="true" fieldOfView="0.785" position="0 200 -130" orientation="-1 0 0 1.571"/>
<Transform DEF="dad_Sole" translation="0 50 700" rotation="-1 0 0 .017">
<PointLight DEF="Sole" containerField="children" ambientIntensity="0.000" intensity="1.000" radius="1000.000" attenuation="1 0 0" color="1 1 1" on="true"/>
</Transform>
<Transform DEF="dad_Strada_DX" containerField="children" translation="16 0 0" rotation="1 0 0 1.571">
<Shape DEF="Strada_DX" containerField="children">
<Appearance containerField="appearance">
<Material DEF="Shiny_Black" containerField="material" ambientIntensity="0.200" shininess="0.100" diffuseColor="0 0 0"/>
</Appearance>
<Box DEF="GeoBox1" containerField="geometry" size="35 430 .0001" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Strada_SX" containerField="children" translation="-16 0 0" rotation="1 0 0 1.571">
<Shape DEF="Strada_SX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Shiny_Black"/>
</Appearance>
<Box DEF="GeoBox2" containerField="geometry" size="35 430 .0001" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga1_DX" containerField="children" translation="10 .05 0">
<Shape DEF="Riga1_DX" containerField="children">
<Appearance containerField="appearance">
<Material DEF="Shiny_White" containerField="material" ambientIntensity="0.200" shininess="0.100" diffuseColor="1 1 1" specularColor="1 1 1"/>
</Appearance>
<Box DEF="GeoBox8" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga2_DX" containerField="children" translation="20 .05 0">
<Shape DEF="Riga2_DX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Shiny_White"/>
</Appearance>
<Box DEF="GeoBox9" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga3_DX" containerField="children" translation="30 .05 0">
<Shape DEF="Riga3_DX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Shiny_White"/>
</Appearance>
<Box DEF="GeoBox10" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga1_SX" containerField="children" translation="-10 .05 0">
<Shape DEF="Riga1_SX" containerField="children">
<Appearance containerField="appearance">
<Material DEF="material" containerField="material" ambientIntensity="0.200" shininess="0.100" diffuseColor="1 1 1" specularColor="1 1 1"/>
</Appearance>
<Box DEF="GeoBox5" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga2_SX" containerField="children" translation="-20 .05 0">
<Shape DEF="Riga2_SX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Shiny_White"/>
</Appearance>
<Box DEF="GeoBox6" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Riga3_SX" containerField="children" translation="-30 .05 0">
<Shape DEF="Riga3_SX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Shiny_White"/>
</Appearance>
<Box DEF="GeoBox7" containerField="geometry" size=".4 .0001 430" solid="false"/>
</Shape>
</Transform>
<Transform DEF="dad_Muro" containerField="children" translation="0 0 -215" rotation="1 0 0 1.571">
<Shape DEF="Muro" containerField="children">
<Appearance containerField="appearance">
<Material DEF="Red" containerField="material" ambientIntensity="0.200" shininess="0.200" diffuseColor=".49804 .49804 .49804"/>
</Appearance>
<Extrusion DEF="GeoExtrusion3" containerField="geometry" creaseAngle="0.175" convex="false" crossSection="
.39885 -2.00308
-.40683 -2.00308
-.40683 -2.00308
-.51053 -.99798
-.99712 -.34386
-.99866 0
.99866 0
.99712 -.31993
.50255 -.99798
.39885 -2.00308" spine="
0 0 0
0 430 0"/>
</Shape>
</Transform>
<Transform DEF="dad_Canaletta_DX" containerField="children" translation="34.3999 -.995 215" rotation="0 -.707 .707 3.142">
<Shape DEF="Canaletta_DX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Red"/>
</Appearance>
<NurbsPatchSurface containerField="geometry" solid="false" ccw="false" uDimension="6" vDimension="2" uOrder="4" vOrder="2" uTessellation="-4" vTessellation="1" uKnot="
0
0
0
0
.33333
.66667
1
1
1
1" vKnot="
0
0
1
1">
<Coordinate containerField="controlPoint" point="
-1.98632 0 -.9994
-1.52138 0 -.46432
-1.00835 0 -.46432
-.47764 0 -.46432
0 0 -.99503
.99066 0 -.99503
-1.98632 430 -.9994
-1.52138 430 -.46432
-1.00835 430 -.46432
-.47764 430 -.46432
0 430 -.99503
.99066 430 -.99503"/>
</NurbsPatchSurface>
</Shape>
</Transform>
<Transform DEF="dad_Canaletta_SX" containerField="children" translation="-34.4 -.995 -215" rotation="1 0 0 1.571">
<Shape DEF="Canaletta_SX" containerField="children">
<Appearance containerField="appearance">
<Material containerField="material" USE="Red"/>
</Appearance>
<NurbsPatchSurface containerField="geometry" solid="false" ccw="false" uDimension="6" vDimension="2" uOrder="4" vOrder="2" uTessellation="-4" vTessellation="1" uKnot="
0
0
0
0
.33333
.66667
1
1
1
1" vKnot="
0
0
1
1">
<Coordinate containerField="controlPoint" point="
-1.98632 0 -.9994
-1.52138 0 -.46432
-1.00835 0 -.46432
-.47764 0 -.46432
0 0 -.99503
.99066 0 -.99503
-1.98632 430 -.9994
-1.52138 430 -.46432
-1.00835 430 -.46432
-.47764 430 -.46432
0 430 -.99503
.99066 430 -.99503"/>
</NurbsPatchSurface>
</Shape>
</Transform>
</Transform>
</xsl:template>
</xsl:stylesheet>

# re: Script negli XSL

Left by Omar Damiani at 29/09/2006 17.21
Gravatar Beh, purtroppo non ho mai utilizzato XMLSpy per sviluppare (e debuggare) XSLT quindi non vorrei fosse coinvolto in qualche modo.

Ad ogni modo, non riesco nemmeno a debuggare correttamente senza avere l'xml che deve essere trasformato.

Errori di sintassi a prima vista non sembrano essercene, ma se ci fosse la possibilità di debuggare sarebbe tutt'altro discorso.

Your comment:





 
Please add 5 and 3 and type the answer here:

Copyright © Omar Damiani

Design by Bartosz Brzezinski

Design by Phil Haack Based On A Design By Bartosz Brzezinski