使用XSL“展开”字符串

时间:2009-08-03 21:36:27

标签: xml xslt string exslt

我们有一个具有层次结构组织的应用程序。有些组以这种格式传递:

/Geography/NA/US/California

我想“展开”此字符串,以便我可以获得如下所示的节点:

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

我知道我可以使用str:tokenize并获得如此的节点集:[Geography, NA, US, California]但我不知道如何逐步将这些部分组合在一起。

我有大多数exslt函数可供使用,但没有XSLT 2.0函数。

任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:2)

在普通的XSLT 1.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')。
  • 忽略单个尾部斜杠。
  • 分隔符冷却很容易推广并作为参数传递。
  • 您可以通过将递归调用放入<token>元素而不是外部来轻松构建层次结构。
  • 通过将递归调用放在<token>元素上方而不是在其下方,可以反转输出顺序(最长到最短)。
  • 您需要使用node-set()扩展功能将返回的令牌转换为可以进一步使用的内容。

答案 1 :(得分:0)

对它进行标记,然后编写一个递归模板concatenates只将你感兴趣的部分组合在一起。(我现在不打算坐下来写这个,但我会使用一个组合XPath和set:leading首先生成完整的节点集,然后生成除最后一个节点之外的所有节点,然后是最后两个节点以外的所有节点,依此类推 - 依此类推 - 您将传递完整的节点集以及您剥离的任何节点最近关闭模板在每次递归时都会参数,直到到达节点集的开头。)

令人高兴的是,这是一个很简单的阶乘式递归,而不像Fibonacci序列那样可怕。