假设以下xml输入...
<incidents>
<incident>
<year>2011</year>
<other data here>
</incident>
<incident>
<year>2009</year>
<other data here>
</incident>
<incident>
<year>2006</year>
</incident>
</incidents>
xml总是按年分类,因此最新的事件年是第一个。我需要使用xsl处理它,并且基本上使用最小变换输出数据5年,最多,但是如果缺少任何年份,我只需要为<incident><year>missingYear</year></incident>
输出一个元素。
因此,假设我有正确的XSL来执行此操作,处理上述xml将产生此...
<incidents>
<incident>
<year>2011</year>
</incident>
<incident>
<year>2010</year>
</incident>
<incident>
<year>2009</year>
</incident>
<incident>
<year>2008</year>
</incident>
<incident>
<year>2007</year>
</incident>
<incident>
<year>2006</year>
</incident>
</incidents>
我用xsl得到了这么多,但它并没有考虑到多年之间的巨大差距
<xsl:variable name="maxYear" select="/incidents/incident/year[1]"></xsl:variable>
<xsl:template match="incidents" >
<xsl:element name="incident">
<xsl:for-each select="incident">
<xsl:variable name="currentYear" select="year"/>
<xsl:choose>
<xsl:when test="($maxYear - (position() -1)) != $currentYear">
<!-- output the missing year -->
<xsl:element name="year"> <xsl:value-of select="($maxYear - (position() -1))" /></xsl:element>
<!-- output the current year node -->
<xsl:element name="year"> <xsl:value-of select="$currentYear" /></xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="year"> <xsl:value-of select="$currentYear" /></xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:element>
</xsl:template>
答案 0 :(得分:2)
<强>予。这是一个完整的XSLT 1.0解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pYearsBack" select="6"/>
<xsl:param name="pThisYear" select="2012"/>
<xsl:variable name="vEarliest" select=
"$pThisYear - $pYearsBack"/>
<xsl:variable name="vYears" select="/*/*/year"/>
<xsl:template match="/">
<incidents>
<xsl:call-template name="genYears"/>
</incidents>
</xsl:template>
<xsl:template name="genYears">
<xsl:param name="pTimes" select="$pYearsBack+1"/>
<xsl:param name="pStart" select="$pThisYear"/>
<xsl:if test="$pTimes > 0">
<incident>
<year>
<xsl:value-of select=
"concat($vYears[. = $pStart],
substring('missingYear',
1 div not($vYears[. = $pStart]))
)
"/>
</year>
</incident>
<xsl:call-template name="genYears">
<xsl:with-param name="pTimes" select="$pTimes -1"/>
<xsl:with-param name="pStart" select="$pStart -1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档(更正为格式良好):
<incidents>
<incident>
<year>2011</year>
<other-data-here/>
</incident>
<incident>
<year>2009</year>
<other-data-here/>
</incident>
<incident>
<year>2006</year>
</incident>
</incidents>
想要的,正确的结果(从$pThisYear
返回$pYearsBack
年开始的所有年度事件)生成:
<incidents>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2011</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2009</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2006</year>
</incident>
</incidents>
<强> II。 XSLT 2.0解决方案:
与往常一样,XSLT 2.0解决方案更容易,更简洁,更易读:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pYearsBack" select="6" as="xs:integer"/>
<xsl:param name="pThisYear" select="2012" as="xs:integer"/>
<xsl:variable name="vEarliest" select=
"$pThisYear - $pYearsBack -1"/>
<xsl:variable name="vYears" select="/*/*/year/xs:integer(.)"/>
<xsl:template match="/">
<incidents>
<xsl:for-each select="1 to $pYearsBack +1">
<xsl:variable name="vthisYear" as="xs:integer"
select="$pThisYear - . +1"/>
<incident>
<year>
<xsl:sequence select=
"($vYears[. eq $vthisYear], 'missingYear')[1]"/>
</year>
</incident>
</xsl:for-each>
</incidents>
</xsl:template>
</xsl:stylesheet>
将此转换应用于同一XML文档(上图)时,会生成相同的正确结果:
<incidents>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2011</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2009</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>missingYear</year>
</incident>
<incident>
<year>2006</year>
</incident>
</incidents>
答案 1 :(得分:1)
如果你希望得到的xml总是包含可预测的元素(在这种情况下,连续几年,没有间隙,即使源文档有多年的空白),那么为什么不编写它(生成的xml)?为什么转换为生成,如果你知道它需要什么?
我可能会夸大一点:)
但这是一个想法:选择最高和最低年份值,或者第一个和最后一个。然后将int值从一端循环到另一端。对于每个循环迭代,查找src xml中的匹配元素。如果找到,则生成其余部分,否则跳过。