假设以下 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>
最佳答案
我。这是一个完整的 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>
二. 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>
关于xml - 根据 XSL 中的条件动态输出元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9089598/