2010-08-22 18 views
6

Ho due file XSL: "one.xsl" e "two.xsl"Come utilizzare una funzione da un xsl in un altro

one.xsl:

<xsl:function name="x:trans" as="xs:string"> 
    <xsl:param name="str"></xsl:param> 
    <xsl:variable name="res1" select="x:translate_string($str)"/> 
    <xsl:sequence select="$res1"/> 
</xsl:function> 
</xsl:stylesheet> 

voglio usare funzione "x: trans" in "one.xsl"

Come si fa riferimento alla funzione in un altro file?


Il problema è che quando provo a chiamare per questa funzione in questo modo:

< xsl:value-of select="x:trans('Hello World')"/> 

ricevo il seguente messaggio di errore dal browser:

riferimento al prefisso del namespace non dichiarato: 'x '

+0

Se è stato importato o incluso "one.xsl", sarà necessario dichiarare lo spazio dei nomi "x" in "two.xsl" se si desidera utilizzarlo. –

+3

Inoltre, si dice che il messaggio dalle funzioni * browser * ... personalizzate ** è una funzionalità XSLT 2.0 **. Attualmente nessun browser supporta XSLT 2.0. Se vuoi che i browser eseguano il tuo XSLT, avrai bisogno di una soluzione * XSLT 1.0 *. –

+0

Buona domanda (+1). Vedi la mia risposta per una spiegazione completa, passo dopo passo, su come chiamare un 'xsl: function'. –

risposta

1

In two.xsl:

<xsl:include href="one.xsl" /> 

Vedere anche la descrizione di includere nello XSLT 2.0 spec.

4

Si desidera eseguire <xsl:include /> o <xsl:import />. <xsl:include /> è più semplice (trascina semplicemente tutto dentro) mentre <xsl:import /> è più flessibile (se ci sono modelli in collisione tra i due, l'over-ride della chiamata da parte della chiamata è meglio definito e generalmente ragionevole).

Modifica per info aggiunto:

È necessario assicurarsi che si chiamano i modelli nel foglio di stile importato utilizzando lo spazio dei nomi gli appositi. Il modo più semplice è assicurarsi di avere corrispondenze xmlns: foo dichiarazioni nei fogli di stile, sebbene si possa chiamare foo: template in un foglio di stile come barra: template nell'altro se avesse xmlns: bar invece.

+0

+1 Generalmente preferisco l'importazione rispetto a include, in quanto fornisce maggiore flessibilità. –

+0

+1 e idem per preferire xsl: import –

+0

Sì! Importa fino in fondo –

7

A parte le risposte corrette che avete bisogno di <xsl:include> o <xsl:import> (vi consiglio quest'ultima come l'ex spesso può provocare errori di duplicazione), l'altro problema è il seguente:

  1. Un nome funzione deve appartenere a uno spazio nomi.

  2. Lo spazio dei nomi deve essere dichiarato (definito e associato a un prefisso) nello stesso file in cui è definita la funzione.

  3. Qualsiasi chiamata alla funzione deve precedere il nome della funzione e che prefisso deve essere vincolato allo stesso dominio cui il nome della funzione appartiene

Ecco un semplice esempio:

I.File deleteA.xsl definisce la funzione my:double

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:my="my:my" 
    > 
<xsl:function name="my:double" as="xs:double"> 
    <xsl:param name="pArg" as="xs:double"/> 

    <xsl:sequence select="2*$pArg"/> 
</xsl:function> 
</xsl:stylesheet> 

II. Del file deleteB.xsl importazioni deleteA.xsl e utilizza la funzione my:double:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:my="my:my"> 
    <xsl:import href="deleteA.xsl"/> 

    <xsl:output method="text"/> 

    <xsl:template match="/"> 
     <xsl:sequence select="my:double(.)"/> 
    </xsl:template> 
</xsl:stylesheet> 

III. La trasformazione contenuta nel deleteB.xsl è applicato sul seguente documento XML:

<t>1</t> 

e il risultato corretto è prodotto:

2 

commento aggiuntivo: Attualmente nessun browser supporta XSLT 2.0 trasformazioni - xsl:function è disponibile solo in XSLT 2.0 +.

Problemi correlati