XSLT中如何根据传入参数protocol条件分配lookup table?
解决XSLT中根据参数条件分配Lookup表的问题
当然可以实现这个需求!我来给你展示具体的写法,帮你搞定条件性选择lookup表的问题,同时达到你想要的输出效果。
首先,先模拟你的固定格式源XML(假设是这样的结构,你可以根据实际调整):
<devices> <device id="1" type="X"/> <device id="2" type="Y"/> </devices>
接下来是完整的XSLT代码,核心是根据protocol参数动态选择对应的lookup表:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 传入的protocol参数,默认设为'A',可在调用时传入'B' --> <xsl:param name="protocol" select="'A'"/> <!-- 定义两个Lookup表 --> <xsl:variable name="TableA" as="element(*)*"> <lookup type="X" value="foo device"/> <lookup type="Y" value="foo device"/> </xsl:variable> <xsl:variable name="TableB" as="element(*)*"> <lookup type="X" value="bar device"/> <lookup type="Y" value="bar device"/> </xsl:variable> <!-- 关键:根据protocol参数动态选择Lookup表 --> <xsl:variable name="selectedLookup" select="if ($protocol = 'A') then $TableA else $TableB"/> <!-- 转换模板 --> <xsl:template match="/"> <output> <xsl:apply-templates select="devices/device"/> </output> </xsl:template> <xsl:template match="device"> <device-info> <!-- 使用选中的Lookup表匹配当前device的type --> <xsl:value-of select="$selectedLookup/lookup[@type = current()/@type]/@value"/> </device-info> </xsl:template> </xsl:stylesheet>
关键要点解释:
- 动态选择Lookup表:用
xsl:variable的select属性结合if表达式,直接根据protocol参数的值返回对应的表节点集,这比用xsl:choose更简洁。 - 正确的上下文匹配:在查找lookup项时,一定要用
current()来获取当前<device>节点的type属性,否则上下文会切换到lookup表节点,导致匹配失败(这很可能是你之前尝试失败的原因!)。 - 变量类型声明:给lookup表变量加上
as="element(*)*",明确告诉XSLT这是节点集类型,避免处理时的隐式类型转换问题。
测试效果:
- 当传入参数
protocol='A'时,输出会是:<output> <device-info>foo device</device-info> <device-info>foo device</device-info> </output> - 当传入参数
protocol='B'时,输出会是:<output> <device-info>bar device</device-info> <device-info>bar device</device-info> </output>
如果你的源XML结构和lookup表的匹配逻辑有细微差别,只需要调整lookup节点的匹配条件(比如用文本值而非属性)即可,核心的动态选择表的逻辑是通用的。
内容的提问来源于stack exchange,提问作者iwarv
相关产品推荐
相关产品推荐

