我有以下xml/xl:
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="./test.xsl"?>
<a>
<b>
<c >
<no>1</no>
<d>
<e>
<f>20060603190000</f>
</e>
</d>
</c>
<c >
<no>1</no>
<d>
<e>
<f>20060603190000</f>
</e>
</d>
</c>
<c>
<no>2</no>
<d>
<e>
<f>20060603190000</f>
</e>
</d>
</c>
<c >
<no>1</no>
<d>
<e>
<f>20060819200000</f>
</e>
<e>
<f>20060902200000</f>
</e>
</d>
</c>
<c >
<no>1</no>
<d>
<e>
<f>20070819200000</f>
</e>
<e>
<f>20070819200003</f>
</e>
<e>
<f>20070819200001</f>
</e>
<e>
<f>20060903100000</f>
</e>
</d>
</c>
<c >
<no>1</no>
<d>
<e>
<f>20060819200000</f>
</e>
<e>
<f>20060902200000</f>
</e>
</d>
</c>
</b>
</a>
<?xml version="1.0" encoding="ISO-8859-15"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" >
<xsl:output method="text" indent="yes" />
<xsl:template match="/">
<table>
<tr>
<xsl:for-each select="a/b/c[no=1]/d/e/f[not(.=preceding::*)]" ><xsl:sort select="." data-type="number"/> 
<td><xsl:value-of select="."/></td>
</xsl:for-each>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
应用时,结果如下:
20060603190000200608192000002006090220000020060903100000200708192000002007081920000120070819200003
这是部分正确的,因为:
我想显示f(有效)的不同值
我想对f(它也起作用)的值进行排序
但是:
我想只显示前8位不同的值(年、月、日),这样结果会是:
2006060319000020060819200000200609022000002006090310000020070819200000
即日期相同但时间不同的值被视为相等。
我曾尝试在不同的地方使用子字符串(values,8),但我无法让它以这种方式工作,也无法使用key/generate-id。有人能给我建议吗?
编辑:
我自己解决了这个问题。
以下模板创建一个字符串,其中包含按时间排序的所有日期,并截断为前8位数字(带时间的日期):
<xsl:template match="/">
<xsl:variable name="text">
<xsl:for-each select="a/b/c[no=1]/d/e/f[not(.=preceding::*)]" ><xsl:sort select="." data-type="number"/>
<xsl:value-of select="substring(.,0,9)"/>-</xsl:for-each>
</xsl:variable>
text:<xsl:value-of select="$text"/>
<xsl:call-template name="filter"><xsl:with-param name="text"><xsl:value-of select="$text"/></xsl:with-param><xsl:with-param name="previousElement"/></xsl:call-template >
</xsl:template>
输出示例:20060603-20060819-0060902-20060902-20060902-20060903-20070819-20070819-20110902-20110902-
然后调用第二个模板,该模板通过递归调用自身来输出不同的值:
<xsl:template name="filter">
<xsl:param name="text"/>
<xsl:param name="previousElement"/>
<xsl:variable name="firstElement"><xsl:value-of select="substring-before($text, '-')"/></xsl:variable>
<xsl:variable name="rest"><xsl:value-of select="substring-after($text, '-')"/></xsl:variable>
<!-- firstElement:<xsl:value-of select="$firstElement"/>
previousElement:<xsl:value-of select="$previousElement"/>
rest:<xsl:value-of select="$rest"/>
-->
<xsl:if test="string-length($firstElement) > 0">
<xsl:choose>
<xsl:when test="$firstElement = $previousElement">
<xsl:call-template name="filter"><xsl:with-param name="text"><xsl:value-of select="$rest"/></xsl:with-param><xsl:with-param name="previousElement"><xsl:value-of select="$firstElement"/></xsl:with-param></xsl:call-template >
</xsl:when>
<xsl:otherwise>
output:<xsl:value-of select="$firstElement"/>
<xsl:call-template name="filter"><xsl:with-param name="text"><xsl:value-of select="$rest"/></xsl:with-param><xsl:with-param name="previousElement"><xsl:value-of select="$firstElement"/></xsl:with-param></xsl:call-template >
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
如上所述,我自己回答了我的问题。根据Marcus Rickert的建议,我会这样回答,并接受它,使它可以关闭,也许对其他人有帮助。