如何在xsl:if中实现类似SQL IN的多值条件匹配功能?
XSLT 1.0实现类似SQL IN多值判断的方法
你不需要写一堆重复的<xsl:if>,以下三种方案都可以实现多值列表匹配,按推荐优先级排序:
方案1:XPath原生节点集匹配(推荐,易维护)
XPath本身就支持单值和节点集的比较规则:当等号左边是单个值,右边是节点集合时,只要集合里任意一个节点的值和左边相等,整个判断就返回true,这个逻辑和SQL的IN完全一致。
针对你20个值映射到3个目标字段的场景,这个方案维护成本最低:
- 首先在样式表根节点加EXSLT通用命名空间声明(绝大多数XSLT 1.0引擎比如libxslt、Xalan、Saxon 6都原生支持这个扩展,无兼容问题):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common" version="1.0"> - 把三个分组的匹配值集中定义为变量,后续改映射规则只需要调整变量内容:
<!-- 映射到crs_udf5.crs.srs的取值列表 --> <xsl:variable name="mapUdf5"> <v>01</v><v>02</v><v>43</v> <!-- 补充所有归到该分组的取值 --> </xsl:variable> <!-- 映射到crs_udf6.crs.srs的取值列表 --> <xsl:variable name="mapUdf6"> <v>03</v><v>07</v><v>22</v> <!-- 补充所有归到该分组的取值 --> </xsl:variable> <!-- 映射到crs_udf7.crs.srs的取值列表 --> <xsl:variable name="mapUdf7"> <v>04</v><v>09</v><v>35</v> <!-- 补充所有归到该分组的取值 --> </xsl:variable> - 判断时直接用节点集比较逻辑,替换原来的单值if判断即可:
<xsl:variable name="currSrs" select="..//sce_moac.sce.srs"/> <xsl:choose> <xsl:when test="$currSrs = exslt:node-set($mapUdf5)/v"> <xsl:value-of select="../../..//crs_udf5.crs.srs"/> </xsl:when> <xsl:when test="$currSrs = exslt:node-set($mapUdf6)/v"> <xsl:value-of select="../../..//crs_udf6.crs.srs"/> </xsl:when> <xsl:when test="$currSrs = exslt:node-set($mapUdf7)/v"> <xsl:value-of select="../../..//crs_udf7.crs.srs"/> </xsl:when> </xsl:choose>
方案2:or逻辑直接拼接(兼容性最高)
如果你的运行环境不支持任何扩展函数,直接把多个判断条件用or拼接即可,不需要额外依赖:
<xsl:if test="..//sce_moac.sce.srs='01' or ..//sce_moac.sce.srs='02' or ..//sce_moac.sce.srs='43'"> <xsl:value-of select="../../..//crs_udf5.crs.srs"/> </xsl:if>
这个写法的缺点是值多了代码冗余度高,后续调整值需要改判断逻辑,适合值数量少的场景。
方案3:contains字符串匹配(无扩展兼容方案)
如果不能用EXSLT的node-set函数,也可以用字符串包含判断实现,必须加分隔符避免子串误匹配:
<!-- 所有值前后都加|分隔,避免短值误匹配长值的子串 --> <xsl:variable name="udf5List" select="'|01|02|43|'"/> <xsl:if test="contains($udf5List, concat('|', ..//sce_moac.sce.srs, '|'))"> <xsl:value-of select="../../..//crs_udf5.crs.srs"/> </xsl:if>
注意:不要省略前后的分隔符,否则会出现比如判断值为
1时,误匹配到列表里11这类值的问题。
额外提醒
你提供的示例XSL里写了两个匹配根节点/的模板,XSLT会用后定义的模板覆盖前面的,前面那个只写了<xsl:apply-templates />的根模板完全无效,可以直接删掉避免冲突。
内容的提问来源于stack exchange,提问作者jonah
相关产品推荐
相关产品推荐

