0

階層グループ構造を持つアプリケーションがあります。一部のグループは、次の形式で渡されます。

/Geography/NA/US/California

次のようなノードセットを取得できるように、この文字列を「展開」したいと思います。

/Geography
/Geography/NA
/Geography/NA/US
/Geography/NA/US/California

str:tokenizeを使用して次のようにノードセットを取得できることはわかっています[Geography, NA, US, California]が、パーツを段階的に元に戻す方法がわかりません。

ほとんどのexslt関数を使用できますが、XSLT 2.0 関数はありません。

どんな助けでも大歓迎です!

4

2 に答える 2

2

これはプレーンなXSLT1.0では非常に簡単です。必要なのは次のような再帰関数だけです。

<xsl:template name="UnrollString">
  <xsl:param name="string" select="''" />
  <xsl:param name="head"   select="'/'" />

  <xsl:variable name="tail" select="
    concat(
      substring-after($string, $head), 
      '/'
    )
  " />
  <xsl:variable name="lead" select="
    concat(
      $head, 
      substring-before($tail, '/')
    )
  " />

  <xsl:if test="not($tail = '/')">
    <token>
      <xsl:value-of select="$lead" />
    </token>

    <xsl:call-template name="UnrollString">
      <xsl:with-param name="string" select="$string" />
      <xsl:with-param name="head"   select="concat($lead, '/')" />
    </xsl:call-template>
  </xsl:if>
</xsl:template>

の出力'/Geography/NA/US/California'は次のとおりです。

<token>/Geography</token>
<token>/Geography/NA</token>
<token>/Geography/NA/US</token>
<token>/Geography/NA/US/California</token>

ご了承ください:

  • この関数は、文字列が区切り文字(つまり、スラッシュ)で始まることを想定しています。そうでない場合、最初の単語('Geography')が出力に含まれません。
  • 末尾のスラッシュは1つ無視されます。
  • デリミタコールドは簡単に一般化され、パラメータとして渡されます。
  • <token>再帰呼び出しを外部ではなく要素に配置することで、階層を簡単に構築できます。
  • <token>要素の下ではなく上に再帰呼び出しを配置することで、出力の順序を逆にすることができます(最長から最短) 。
  • node-set()返されたトークンをさらに使用できるものに変換するには、拡張関数を使用する必要があります。
于 2009-08-04T09:19:04.093 に答える
0

トークン化してから、関心のある部分だけを連結する再帰テンプレートを作成します(今は座ってこれを作成するつもりはありませんが、XPathとset:leadingを組み合わせて作成します。最初に完全なノードセット、次に最後のノードを除くすべて、次に最後の2つのノードを除くすべて、というように続きます。完全なノードセットと、最近削除したノードをそれぞれのテンプレートパラメータとして渡します。ノードセットの先頭に到達するまでの再帰。)

幸いなことに、これは素晴らしく単純な階乗のような再帰であり、フィボナッチ数列のような恐ろしいものではありません。

于 2009-08-03T21:58:00.370 に答える