2009-08-27 9 views
6

私はXSLTのブロックを持っています。しかし、私は実際にそれが最初に適用されたときに実行したい、それはすべてのsubiquent時間をスキップする必要があります。これはどうすればいいですか?XSLTでは、テンプレートを1回だけ実行できます

<xsl:variable name="run_once" select="0"/> 
その後

私はテンプレートと呼ばれているいくつかの回:

私はグローバル変数を定義するスタイルシートで :例として

が、これは私がやりたいものの一種であります
<xsl:template name="some_template"> 
    <xsl:if test="$run_once != 1"> 
     <xsl:variable name="run_once" select="1"/> 
     <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text> 
    </xsl:if> 
</xsl:template> 

変数は変更できず、オーバーロードされるだけなので、これはもちろん機能しません。したがって、some_templateが$ run_onceを終了すると、再び0になり、テンプレートが呼び出されるたびにテキストが適用されます。 ifdef機能や設定可能な他のグローバルオブジェクトがありますか?あなたは、私がこれをしたい理由に興味がある場合は

は、以下の私の問題のより詳細な説明と、私が使用した溶液である:

  • 私の入力は、生のXML内のデータがあり、私の が出力されますWordML形式のレポート。
  • 入力には、ノード (Node)という一連のノードがあります。これらのノードのうちの一部は、 すべてが出力に表示される である必要があります。ノード は、XPATH hairyLogicがtrue(hairyLogicは明らかに長く、 複合体)の場合にのみ表示されます。
  • theNodeのタイプ(サブノード に格納)もあります。入力では、同じタイプのすべての のノードは常に と一緒にグループ化されます。 出力では、同じ タイプのすべてのノードは、そのタイプの特定の見出しである の下にグループ化する必要があります( は、 タイプごとに1つの見出しにする必要があります)。

これは私が使用して終了ソリューションです:

... 
<xsl:apply-templates select="theNode[hairyLogic]"/> 
... 

<xsl:template match="theNode"> 
    <xsl:if test="count(preceding-sibling::theNode[type = current()/type and hairyLogic])=0"> 
     <xsl:choose> 
      <xsl:when test="type = 'TYPE1a' or type = 'TYPE1b'"> 
       <xsl:call-template name="TYPE1Heading"/> 
      </xsl:when> 
      <xsl:when test="type = 'TYPE2'"> 
       <xsl:call-template name="TYPE2Heading"/> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:if> 
    ... 
</xsl:template> 

私は、彼らが入力XML内の任意のデータに依存しない基本のWordMLが含まれているため見出しに名前付きテンプレートを使用することにしました。

hairyLogicが繰り返され、if文が畳み込まれて読みにくいので、私はこの解決策が気に入らない。可変変数を必要としない優れたソリューションがありますか?

答えて

2

マッチテンプレートを名前付きテンプレートよりも使用することをお勧めします。これは、XSLTがpythonicに相当しますXslt-y?私はあなたがその処理方法論で問題をより簡単に解決できることを知っていると思います。

不明な要件があるため、名前付きテンプレートの使用を強くお勧めする場合は、最初のインスタンスを簡単に検出できるようにロジックをリファクタリングすると、ロジックが単純化されます。

あなたが最初のインスタンスが必要になったときに検出できない理由として明確にすることはできますか?私たちはおそらく、あなたが望むようにするxpath式を手助けすることができます。例えば。 XSLT以来

<xsl:template name="some_template"> 
    <xsl:variable name="EXPRESSION" select=".[somelogic='true']"/> 
    <xsl:if test="$EXPRESSION"> 
     <xsl:text>THIS TEXT SHOULD APPEAR ONLY ONCE</xsl:text> 
    </xsl:if> 
</xsl:template> 

は決定的である - グレッグはそれを置くとして完全に機能という効果 - (あなたは奇妙な拡張子のものをやっている場合を除き)初めての入力にロジックを適用することにより、適切な場合、あなたが決めることができます。また、テンプレート内のコンテキストノードにアクセスして、どこから呼び出されているかを知ることができます。

+0

"PythonicのXSLT Equivilentは何ですか?Xslt-y?" - それは "宣言的"です –

+0

はい、私は完全に詳細を述べなかったという制約があります(興味があれば質問に追加されます)。私は、あなたが記述する方法で問題を解決しました。私はそれが好きではありません。なぜなら、「somelogic」は長く、汚れていて、何度か繰り返されているからです。私が他の関数型言語のようにXPATHコードを解析するときに指示することができれば、それほど悪くはありません。次に、私は変数に "somelogic"という悪いビットを格納し、必要に応じてそれを私の式に挿入することができました。 – oillio

2

XSLTは完全に機能する言語であるため、設定できるグローバル変数はです。

代わりにsome_templateテンプレートと呼ばれる状況を選択する必要があります。一度だけ呼び出す場合は、1回だけ呼び出します。

関連する問題