能否使用key()配合xsl:key简化存在重复判断的XSLT代码?
XSLT代码简化方案
你需要的核心是把重复的面额存在性判断逻辑抽离,避免重复编写,这里提供两种常用实现方案,优先推荐更直观的预筛选变量方案,也同时提供你提到的<xsl:key>实现思路。
方案1:预筛选有效货币节点(最简洁,推荐)
直接一次性把所有符合条件的currency节点筛选出来存为节点集变量,后续所有操作都直接使用这个已经过滤好的节点序列即可,判断逻辑仅需要写1次:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:variable name="test"> <root> <other1> </other1> <currency g="1"> <sth1>A</sth1> <thousand>1</thousand> <hundred>2</hundred> <fifty>4</fifty> <one>10</one> <sth2>C</sth2> </currency> <currency g="2"> <sth1>A</sth1> <sth2>C</sth2> </currency> <currency g="3"> <sth1>A</sth1> <thousand>1</thousand> <hundred>2</hundred> <fifty>4</fifty> <one>10</one> <sth2>C</sth2> </currency> <other2> </other2> </root> </xsl:variable> <xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="curr" select="xalan:nodeset($test)/root"/> <!-- 新增:一次性筛选所有有效货币节点,判断逻辑仅写1次 --> <xsl:variable xmlns:xalan="http://xml.apache.org/xalan" name="validCurrencies" select="$curr/currency[thousand or hundred or fifty or one]"/> <xsl:template match="/"> <root> <xsl:call-template name="currency"/> </root> </xsl:template> <xsl:template name="currency"> <!-- 直接遍历预筛选的有效节点 --> <xsl:for-each select="$validCurrencies"> <xsl:if test="position() mod 3 = 1"> <!-- 直接在有效节点序列里取对应位置的后续节点,无需额外判断 --> <xsl:variable name="pos" select="position()"/> <xsl:variable name="nextSibling1" select="$validCurrencies[$pos + 1]"/> <xsl:variable name="nextSibling2" select="$validCurrencies[$pos + 2]"/> <col1> <xsl:apply-templates select="." mode="total"/> </col1> <col2> <xsl:apply-templates select="$nextSibling1" mode="total"/> </col2> <col3> <xsl:apply-templates select="$nextSibling2" mode="total"/> </col3> </xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="currency" mode="total"> <xsl:value-of select="thousand*1000 + hundred*100 + fifty*50 + one"/> </xsl:template> <xsl:template match="*"/> </xsl:stylesheet>
运行结果和原代码完全一致:
<root> <col1>1410</col1> <col2>1410</col2> <col3/> </root>
方案2:使用<xsl:key>实现(符合你提到的思路)
如果你偏好使用key实现,可以按如下方式定义和使用:
<!-- 定义key,匹配有效currency节点,用g属性作为索引 --> <xsl:key name="validCurrency" match="currency[thousand or hundred or fifty or one]" use="@g"/>
使用时直接通过key('validCurrency', @g)即可判断当前currency是否有效,也可直接通过key('validCurrency', /*)获取所有有效节点。不过对于这个场景,方案1的预筛选变量写法更简洁易懂,维护成本更低。
内容的提问来源于stack exchange,提问作者Guasqueño
相关产品推荐
相关产品推荐

