2012-09-06 16 views
12

Bir şablona değişken bir değere bağlı olan bir mod uygulamak istiyorum.Uygulamanın şablonları şablonundaki bir değişkenin değerini kullanın

<xsl:variable name="mode" select="@attribute"/> 
<xsl:apply-templates mode="{$mode}"/> 

Stil sayfasının derlenememesi hatası alıyorum. Modun değeri bir QName olmalıdır, ancak "{$ mode}" dır.

Değişkenlere bağlı modları kullanmak için bir olasılık var mı?

+0

Aynı etkiyi elde etmek için, FXSL kütüphanesinin temeli olan "şablon referansı" ilkesini kullanarak. –

+0

Bu fikir için teşekkür ederiz! Bunu anlamaya çalıştım ama XSLT'de yeniyim ve fonksiyonel programlama konusunda fazla tecrübem yok. Tarif edilen vaka için, "aşırı mühendislik" dir. Belki, daha fazla deneyime sahip olduğumda, bunu bazen kullanabilirim. – maria90

+0

maria90, Böyle bir tekniğin var olduğunu bilmek yeterlidir - sonra gerektiğinde kullanmak için. –

cevap

7

bir ifadeye dayanarak belirli modunu kullanmak zorunda tek seçenek

<xsl:choose> 
    <xsl:when test="@attribute = 'foo'"> 
     <xsl:apply-templates mode="bar"/> 
    </xsl:when> 
    <xsl:otherwise> 
     <xsl:apply-templates/> 
    </xsl:otherwise> 
</xsl:choose> 

veya xsl:if ile aynı kullanmaktır. mode öznitelik değerinin, XSLT 2.0'da sırasıyla XSLT 1.0'da bir QName olması gerekir; QName veya #current veya #default 'gibi özel belirteçler sağlar. Ancak, çalışma zamanında mode değerini hesaplayamazsınız.

+0

Bu, sorunu çözmek için ilk fikrimdi. Değişkenin belirli değerlerini test etmekten kaçınmak istedim. Yine de, bu şekilde kullanacağım çünkü FXSL benim için biraz ağır. – maria90

3

modu, Attribute Value Templates (AVT) için geçerli bir aday değil. Bunu yapamazsın. XSLT 2.0 spec kaynaktan

:

[Tanım: örneğin, bir birebir hedef elemanın bir özelliği olarak, bir özellik değeri olarak şablon belirlenen bir nitelik olarak, bir sentezleme ifadesini çevreleyen tarafından kullanılabilir köşeli parantezler ({})] ile. ou bunu yapamaz böylece

modu, spec AVT olarak belirlenmiş değildir.

0

Stil sayfasının derlenememesi hatası alıyorum. modunun değeri bir QName olmalıdır, ancak "{$ mode}" şeklindedir.

Değişkenlere bağlı modları kullanmak için bir olasılık var mı?

Hayır, bu herhangi bir XSLT sürümünde desteklenmez - 1.0, 2.0 veya 3.0.

sen (HOF) Yüksek Dereceli Fonksiyonlar taklit etkisi çalışıyoruz olarak, XSLT'de 1.0 bunu yapmanın FXSL temel prensibi kullanabilir.

FXSL 1.x, HOF'ı destekleyen/öykünen salt XSLT 1.0 ile yazılmış bir şablon kütüphanesidir.İşte

bu ilkelere dayalı tam bir çözümdür:

bu dönüşümün aşağıdaki XML belgesindeki uygulanır
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:f="http://fxsl.sf.net" exclude-result-prefixes="f"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

    <f:inc/> 
    <f:double/> 

<xsl:variable name="vModeInc" select="document('')/*/f:inc[1]"/> 
<xsl:variable name="vModeDouble" select="document('')/*/f:double[1]"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <nums> 
    <xsl:apply-templates select="$vModeInc"> 
     <xsl:with-param name="pNodes" select="node()"/> 
    </xsl:apply-templates> 
    </nums> 
============== 
    <nums> 
    <xsl:apply-templates select="$vModeDouble"> 
     <xsl:with-param name="pNodes" select="node()"/> 
    </xsl:apply-templates> 
    </nums> 
</xsl:template> 

<xsl:template match="f:inc"> 
    <xsl:param name="pNodes"/> 
    <xsl:apply-templates select="$pNodes" mode="incr"/> 
</xsl:template> 

<xsl:template match="f:double"> 
    <xsl:param name="pNodes"/> 
    <xsl:apply-templates select="$pNodes" mode="double"/> 
</xsl:template> 

<xsl:template match="num" mode="incr"> 
    <num><xsl:value-of select=".+1"/></num> 
</xsl:template> 

<xsl:template match="num" mode="double"> 
    <num><xsl:value-of select=".*2"/></num> 
</xsl:template> 
</xsl:stylesheet> 

:

<nums> 
    <num>01</num> 
    <num>02</num> 
    <num>03</num> 
    <num>04</num> 
    <num>05</num> 
    <num>06</num> 
    <num>07</num> 
    <num>08</num> 
    <num>09</num> 
    <num>10</num> 
</nums> 

aranan doğru sonuçtur Üretilen - mevcut iki modun birinde (her birinde) işlenen nums/num öğeleri değişkeni bekleyen belirtilen - $vModeInc (her değer iki ile çarpılır) veya $vModeDouble (1 her değer eklenmiş):

sözdizimsel yasadışı, ancak XSLT'de 1.0 * mümkün * Ne yapmak istiyorsun
<nums> 
    <num>2</num> 
    <num>3</num> 
    <num>4</num> 
    <num>5</num> 
    <num>6</num> 
    <num>7</num> 
    <num>8</num> 
    <num>9</num> 
    <num>10</num> 
    <num>11</num> 
</nums> 
============== 
    <nums> 
    <num>2</num> 
    <num>4</num> 
    <num>6</num> 
    <num>8</num> 
    <num>10</num> 
    <num>12</num> 
    <num>14</num> 
    <num>16</num> 
    <num>18</num> 
    <num>20</num> 
</nums> 
+0

+1 Bu zekice. FXSL'ye devam etmedim, ama bunu yapmak için zamanım olsaydı. :-) Okuyan herkes için, yukarıdaki XSLT'yi izlemek ve ne yaptığını görmek için zaman ayırmaya değer. – LarsH

+0

@LarsH, Teşekkürler, sadece FXSL 2'deki Extreme Markup Languages ​​belgesini okuyun - çok fazla zaman almaz. :) –

+0

Bu makaleye bir link verebilir misiniz? Ben googled ve bu bulundu: her ikisi de kırılmış olan 2 kağıda bağlantıları olan http://fxsl.sourceforge.net/. Oh, bu mu? http://conferences.idealliance.org/extreme/html/2006/Novatchev01/EML2006Novatchev01.html – LarsH

İlgili konular