2016-10-05 7 views
3

例:XSLTでは、関数へのポインタを持つことは可能ですか?

<xsl:function name="my:function" as="xs:integer"> 
    <xsl:param name="pNum" as="xs:integer" /> 
    <xsl:sequence select="$pNum * 2" /> 
</xsl:function> 

<xsl:sequence select="my:function(1)" /> 

私はその可能ならば、この機能にはいくつかの参照を保持し、my:functionを呼び出すことができるようにしたいです。

次のコードではない仕事が、私が何をしようとしていますかを示すためにintented行います

<xsl:variable name="vFn" select="my:function" /> 
<xsl:sequence select="$vFn(5)" /> 

を、私はそれを変換するには、mardown形式で、プレーンテキストファイルに対して変換実行していますhtml。 XML文書で操作していないことが複雑かどうかはわかりません。

答えて

4

Dimitre Novatchevは、XSLT 2.0で機能するこれを行う方法を考案しました(または、1.0の場合でも、ノードセットの拡張子を使って名前付きテンプレートを関数に置き換えた場合)。 (彼はまた、この技術を利用するFXSLと呼ばれるライブラリを作成しました)。

機能にちなんで名付けられた要素を保持する変数を作成します。

<xsl:variable name="my:function" as="element()"> 
    <my:function/> 
</xsl:variable> 

次に、この要素にマッチして関数を呼び出すテンプレートルールを作成します。

<xsl:template mode="dyn" match="my:function"> 
    <xsl:param name="p1"/> 
    <xsl:sequence select="my:function($p1)"/> 
</xsl:template> 

は今すぐ実行する関数を定義ダイナミックコール:

<xsl:function name="dyn:call"> 
    <xsl:param name="function"/> 
    <xsl:param name="param"/> 
    <xsl:apply-templates select="$function" mode="dyn"> 
    <xsl:with-param name="p1" select="$param"/> 
    </xsl:apply-templates> 
</xsl:function> 

ここで変数を使用できますここでは機能の代用として、

... select="dyn:call($my:function, 2)"/> 
2

としてそれを呼び出すI.は、私がFXSLに使用される技術XSLT 1.0の例である:

<xsl:stylesheet version = "1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:f1="8B9C63F4-F4AB5D11-994A0001-B4CD626F" 
    xmlns:f2="AB02AC1C-1C65B3FF-77C5FFFE-4B329DA1" > 
    <f1:f1/> 
    <f2:f2/> 

    <xsl:variable name = "vFun1" select = "document('')/*/f1:*[1]" /> 
    <xsl:variable name = "vFun2" select = "document('')/*/f2:*[1]" /> 

    <xsl:template match="f1:*"> 
     <xsl:param name = "pX" /> 
     <xsl:value-of select = "2 * $pX" /> 
    </xsl:template> 

    <xsl:template match="f2:*"> 
     <xsl:param name = "pX" /> 
     <xsl:value-of select = "3 * $pX" /> 
    </xsl:template> 

    <xsl:template match = "/"> 
    <xsl:call-template name = "mySum" > 
     <xsl:with-param name = "pX" select = "3" /> 
     <xsl:with-param name = "pFun1" select = "$vFun1" /> 
     <xsl:with-param name = "pFun2" select = "$vFun2" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name = "mySum" > 
    <xsl:param name = "pX" /> 
    <xsl:param name = "pFun1" select = "/.." /> 
    <xsl:param name = "pFun2" select = "/.." /> 

    <xsl:variable name = "vFx_1" > 
     <xsl:apply-templates select = "$pFun1" > 
     <xsl:with-param name = "pX" select = "$pX" /> 
     </xsl:apply-templates> 
    </xsl:variable> 

    <xsl:variable name = "vFx_2" > 
     <xsl:apply-templates select = "$pFun2" > 
     <xsl:with-param name = "pX" select = "$pX" /> 
     </xsl:apply-templates> 
    </xsl:variable> 

    <xsl:value-of select = "$vFx_1 + $vFx_2" /> 
    </xsl:template> 
</xsl:stylesheet> 

mySumという名前のテンプレートが2渡されます1つの引数の "関数へのポインタ"であるパラメータと、この1つの引数の値。

これらの動的に渡された関数のそれぞれを呼び出し、結果の合計を生成します。したがって、結果はでなければなりません1)double(x)及び2)triple(x)

5*x

そして実際、結果は15ある、すなわち:であるdouble(x) + triple(x)、上記定義された2つの関数であるよう

5 * 3。この変換は、実際には使用されていないXML文書(<t/>など)に適用されます。

2つの機能を修正し、正しい結果が得られるたびに表示することをお勧めします。


II。 XSLT 2.0実装

あなたが見ることができるように、ここでの呼び出しは、実際に正確に二つの機能として思える渡し:

    f:applyAndSum(f:funTwice(), f:funFiveTimes(), 3) 
    
    
    
    <xsl:stylesheet version="2.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:function name="f:apply"> 
        <xsl:param name="pFunc" as="element()"/> 
        <xsl:param name="arg1"/> 
    
        <xsl:apply-templates select="$pFunc" mode="f:FXSL"> 
         <xsl:with-param name="arg1" select="$arg1"/> 
        </xsl:apply-templates> 
        </xsl:function> 
    
        <xsl:function name="f:apply"> 
        <xsl:param name="pFunc" as="element()"/> 
        <xsl:param name="arg1"/> 
        <xsl:param name="arg2"/> 
    
        <xsl:apply-templates select="$pFunc" mode="f:FXSL"> 
         <xsl:with-param name="arg1" select="$arg1"/> 
         <xsl:with-param name="arg2" select="$arg2"/> 
        </xsl:apply-templates> 
    </xsl:function> 
    
        <xsl:template match="/"> 
        <xsl:sequence select= 
         "f:applyAndSum(f:funTwice(), f:funFiveTimes(), 3)"/> 
        </xsl:template> 
    
        <xsl:function name="f:applyAndSum"> 
        <xsl:param name="arg1" as="element()"/> 
        <xsl:param name="arg2" as="element()"/> 
        <xsl:param name="arg3"/> 
    
        <xsl:sequence select= 
         "f:apply($arg1,$arg3) + f:apply($arg2,$arg3)"/> 
        </xsl:function> 
    
        <xsl:function name="f:funTwice" as="element()"> 
        <f:funTwice/> 
        </xsl:function> 
    
        <xsl:function name="f:funFiveTimes" as="element()"> 
        <f:funFiveTimes/> 
        </xsl:function> 
    
        <xsl:template match="f:funTwice" mode="f:FXSL"> 
        <xsl:param name="arg1"/> 
    
        <xsl:sequence select ="f:funTwice($arg1)"/> 
        </xsl:template> 
    
        <xsl:template match="f:funFiveTimes" mode="f:FXSL"> 
        <xsl:param name="arg1"/> 
    
        <xsl:sequence select ="f:funFiveTimes($arg1)"/> 
        </xsl:template> 
    
        <xsl:function name="f:funTwice"> 
        <xsl:param name="arg1"/> 
    
        <xsl:sequence select="2*$arg1"/> 
        </xsl:function> 
    
        <xsl:function name="f:funFiveTimes"> 
        <xsl:param name="arg1"/> 
    
        <xsl:sequence select="5*$arg1"/> 
        </xsl:function> 
    </xsl:stylesheet> 
    

    そして、ここではFXSLに、より体系的な導入のための2つのリンクがあります

  1. original FXSL page - これは単なるXSLT 1.0です。

  2. paper about FXSL 2 - FXSL for XSLT 2.0

関連する問題