您可以使用xsl:for-each-group
与@group-adjacent
测试为number()
值减去position()
。
这一招显然是由David Carlisle发明,according to Michael Kay.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vals"
select="tokenize(root/ref/@id, '\s?value0*')[normalize-space()]"/>
<xsl:variable name="condensed-values" as="item()*">
<xsl:for-each-group select="$vals"
group-adjacent="number(.) - position()">
<xsl:choose>
<xsl:when test="count(current-group()) > 1">
<!--a sequence of successive numbers,
grab the first and last one and join with '-' -->
<xsl:sequence select="
string-join(current-group()[position()=1
or position()=last()]
,'-')"/>
</xsl:when>
<xsl:otherwise>
<!--single value group-->
<xsl:sequence select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:variable>
<xsl:value-of select="string-join($condensed-values, ',')"/>
</xsl:template>
</xsl:stylesheet>
这是一个伟大的答案。有一件事对我来说是缺失的。我如何测试组是否是最后一项而不输出“,”? – Jeff
它不应该有一个尾随逗号。你执行了它吗? string-join()将使用第二个字符串参数的值连接第一个参数中序列的值,并且不会附加到最后一个项目。 –
我明白了。我必须修改我需要输出的内容。我需要将每个项目包装在单独的标记中,以便从执行中删除字符串连接。 – Jeff