Я надеюсь, что вы не слишком упростили проблему, задав вопрос по SO, потому что это не должно быть такой большой проблемой.
Вы можете определить шаблон и рекурсивно вызывать его, если вы сохраняете формат входной строки согласованным.
Например,
<xsl:template name="TrimMulti">
<xsl:param name="InputString"/>
<xsl:variable name="RemainingString"
select="substring-after($InputString,';#')"/>
<xsl:choose>
<xsl:when test="contains($RemainingString,';#')">
<xsl:value-of
select="substring-before($RemainingString,';#')"/>
<xsl:text>, </xsl:text>
<xsl:call-template name="TrimMulti">
<xsl:with-param
name="InputString"
select="substring-after($RemainingString,';#')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$RemainingString"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Я протестировал этот шаблон с помощью следующего вызова:
<xsl:template match="/">
<xsl:call-template name="TrimMulti">
<xsl:with-param name="InputString">19;#John Smith;#17;#Ben Reynolds;#1;#Terry Jackson</xsl:with-param>
</xsl:call-template>
</xsl:template>
И получил следующий вывод:
John Smith, Ben Reynolds, Terry Jackson
Что, кажется, то, что вы ищете.
Объяснение того, что он делает, легко объяснить, если вы знакомы с функциональным программированием. Параметр InputString
всегда имеет форму [number];#[name];#[rest of string]
. Каждый вызов шаблона TrimMulti
отсекает часть [number];#
и печатает часть [name]
, а затем рекурсивно передает оставшееся выражение себе.
Базовый случай - это когда InputString
имеет форму [number];#[name]
, в этом случае переменная RemainingString
не будет содержать ;#
. Поскольку мы знаем, что это конец ввода, на этот раз мы не выводим запятую.