如何在XSLT中过滤空结果?XSLT 2.0优化需求
用XSLT 2.0简化空字段判断的复用方案
既然你已经升级到XSLT 2.0,完全可以摆脱重复写空值判断的麻烦!下面给你几个实用的方案,按需选择:
1. 通用模板(最推荐,复用性拉满)
写一个可复用的模板,把“判断节点存在+输出目标元素”的逻辑封装起来,以后每个字段只需要调用模板就行:
<xsl:template name="render-existing-field"> <!-- 传入源节点和目标元素的名称 --> <xsl:param name="source-node" required="yes"/> <xsl:param name="target-element" required="yes"/> <!-- XSLT2.0里直接用节点本身判断是否存在,空序列会被视为false --> <xsl:if test="$source-node"> <xsl:element name="{$target-element}" namespace="Namespace"> <xsl:value-of select="$source-node"/> </xsl:element> </xsl:if> </xsl:template>
调用的时候超简单,比如你原来的场景:
<xsl:call-template name="render-existing-field"> <xsl:with-param name="source-node" select="ns2:value"/> <xsl:with-param name="target-element" select="'hasThisValue'"/> </xsl:call-template>
2. 一行式条件构造(适合零散字段)
如果只是偶尔处理单个字段,用XSLT2.0的元素构造语法可以一行搞定,不用写冗余的if块:
<xsl:sequence select="if (ns2:value) then element(Namespace:hasThisValue, ns2:value) else ()"/>
这里element()函数会在ns2:value存在时创建指定命名空间的元素,并填入值,不存在就输出空序列(相当于什么都不生成)。
3. 批量处理多字段(适合大量字段场景)
如果要处理几十个类似字段,可以先定义字段映射,然后遍历映射批量生成输出,不用逐个写逻辑:
<!-- 定义源字段和目标元素的映射 --> <xsl:variable name="field-map" as="element(map)*"> <map source="ns2:value" target="hasThisValue"/> <map source="ns2:age" target="hasAge"/> <map source="ns2:name" target="hasName"/> <!-- 继续添加更多映射 --> </xsl:variable> <!-- 遍历映射批量生成 --> <xsl:for-each select="$field-map"> <xsl:variable name="source" select="*[local-name()=substring-after(@source, ':') and namespace-uri()=namespace-uri(ns2:value)]"/> <xsl:if test="$source"> <Namespace:{@target}> <xsl:value-of select="$source"/> </Namespace:{@target}> </xsl:if> </xsl:for-each>
小提示:
你之前代码里的$TestVar != null其实在XSLT里并不严谨——XSLT没有null概念,空节点序列或者空字符串会被视为“假”。在XSLT2.0里,直接用test="$source-node"就可以判断节点是否存在且非空,比原来的写法更简洁准确。
内容的提问来源于stack exchange,提问作者Joseph Shea
相关产品推荐
相关产品推荐

