0

次のように、カンマ区切りの文字列を分割しています。

<xsl:call-template name="SimpleStringLoop">
    <xsl:with-param name="input" select="'1,2,3,4,'"/>
</xsl:call-template>

<xsl:template name="SimpleStringLoop">
    <xsl:param name="input"/>
    <xsl:if test="string-length($input) &gt; 0">
      <xsl:variable name="v" select="substring-before($input, ',')"/>
      <xsl:value-of select="$v"/>
      <xsl:call-template name="SimpleStringLoop">
        <xsl:with-param name="input" select="substring-after($input, ',')"/>
      </xsl:call-template>
    </xsl:if> 
</xsl:template>

配列のように抽出されたすべての値にアクセスするにはどうすればよいですか? それらのすべてにアクセスし、xslt フィルタリングで使用する必要があります。SimpleStringLoop が呼び出されると、$v は最初は値 1 を保持し、別のときは値 2 を保持するというようになります。しかし、$v[1]、$v[2] のような配列でインデックスを使用するように $v を利用する方法はありますか

ので、私は持っています$v[1]=1, $v[2] =2 etc..

または、私はこの再帰プロセスをまったく理解していないほど愚かですか??

4

2 に答える 2

3

Michael Kay が言うように、XSLT 2.0 はシーケンスを簡単に処理できるので、ここではあなたの友人になるでしょう。実際、便利な tokenize 関数を使用して文字列を分割できるため、再帰的なテンプレートも必要ありません。

<xsl:variable name="fields" select="tokenize($input, ',')" />

次に、たとえば、2 番目のフィールドを取得するには、次のようにします。

<xsl:value-of select="$fields[2]"/>

しかし、XSLT 1.0 に固執している場合は、追加の作業を行う必要があります。現時点では、再帰テンプレートは一連の文字を出力するだけです。これらは結果ツリーの一部であるため、XSLT は最初はそれらにアクセスできません。ただし、この時点で行う必要があるのは、代わりに要素を出力することです。

  <xsl:variable name="v" select="substring-before($input, ',')"/>
  <field>
    <xsl:value-of select="$v"/>
  </field>

次に、既存のxsl:call-templateを変数にラップして、テンプレート呼び出しの結果へのアクセスを開始できるようにする必要があります。

<xsl:variable name="fields">
  <xsl:call-template name="SimpleStringLoop">
    <xsl:with-param name="input" select="'1,2,3,4,'"/>
  </xsl:call-template>
</xsl:variable>

現在、フィールド変数はこの時点で「結果ツリーのフラグメント」を保持していますが、その中のノードにアクセスできるようにしたいと考えています。ここで拡張関数の出番です。結果ツリーのフラグメントをノード セットに変換できる拡張機能があるため、XSLT 関数を使用できます。これは、使用する名前空間に関してプロセッサに大きく依存しますが、最終的には次のようなものを書くことができます:

 <xsl:value-of select="msxml:node-set($fields)/field[2]"/>

例として、この XSLT を試してください。ここでは、Mircosoft の XSLT プロセッサを使用していることに注意してください。他の XSLT プロセッサが利用可能です....

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxml="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxml">
  <xsl:template match="/*">
    <xsl:variable name="fields">
      <xsl:call-template name="SimpleStringLoop">
        <xsl:with-param name="input" select="'1,2,3,4,'"/>
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="msxml:node-set($fields)/field[2]"/>
  </xsl:template>

  <xsl:template name="SimpleStringLoop">
    <xsl:param name="input"/>
    <xsl:if test="string-length($input) &gt; 0">
      <xsl:variable name="v" select="substring-before($input, ',')"/>
      <field>
        <xsl:value-of select="$v"/>
      </field>
      <xsl:call-template name="SimpleStringLoop">
        <xsl:with-param name="input" select="substring-after($input, ',')"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

ノードセットの詳細については、次のリンクを最初に試してください。

http://www.xml.com/pub/a/2003/07/16/nodeset.html

于 2013-08-30T06:51:24.000 に答える
2

XSLT 2.0 が必要です。XSLT 1.0 には、一連の文字列を処理するためのデータ型がありません。変数内の文字列を含むノード セットを作成できます。exslt:node-set() 拡張機能があれば、ノード セットを処理できますが、代用としては不十分です。アップグレードする時間です。

于 2013-08-29T21:43:20.463 に答える