XSLT中是否存在直接匹配空序列/节点集的方法?
XSLT空序列/节点集匹配的解决方案
首先明确:XSLT中没有像你设想的Empty(SomeStuff)这种直接匹配空序列的模板语法。模板匹配的目标是节点(XSLT 2.0及以上还支持原子值),空序列没有可匹配的实体,因此无法直接通过模板匹配它。
不过可以通过更简洁的写法替代你原来的繁琐代码,以下是几种优化方案:
方案1:简化XSLT 1.0中的条件判断
把原有的xsl:if和apply-templates合并到xsl:choose中,减少冗余:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:choose> <xsl:when test="stuff/SomeStuff"> <xsl:apply-templates select="stuff/SomeStuff"/> </xsl:when> <xsl:otherwise> <bar/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="SomeStuff"> <foo/> </xsl:template> </xsl:stylesheet>
方案2:利用父节点模板处理(全XSLT版本适用)
将判断逻辑移到父节点stuff的模板中,主模板只需转发处理,结构更清晰:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="stuff"/> </xsl:template> <xsl:template match="stuff"> <xsl:apply-templates select="SomeStuff"/> <xsl:if test="not(SomeStuff)"> <bar/> </xsl:if> </xsl:template> <xsl:template match="SomeStuff"> <foo/> </xsl:template> </xsl:stylesheet>
方案3:XSLT 2.0+的简洁写法
在XSLT 2.0及以上版本中,可以使用empty()函数简化条件判断,代码更紧凑:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="stuff/SomeStuff"/> <xsl:if test="empty(stuff/SomeStuff)"> <bar/> </xsl:if> </xsl:template> <xsl:template match="SomeStuff"> <foo/> </xsl:template> </xsl:stylesheet>
虽然XSLT没有提供类似函数式语言中Option/Maybe类型的None匹配语法,但通过上述优化方案,同样可以实现简洁、易维护的代码逻辑。
内容的提问来源于stack exchange,提问作者MrD at KookerellaLtd
相关产品推荐
相关产品推荐

