我有一种情况需要检查可能连续编号的属性值,并在开始值和结束值之间输入短划线。
<root>
<ref id="value00008 value00009 value00010 value00011 value00020"/>
</root>
理想的输出是......
8-11, 20
我可以将属性标记为单独的值,但我不确定如何检查“valueXXXXX”末尾的数字是否与前一个值相同。
我正在使用XSLT 2.0
答案 0 :(得分:4)
您可以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>