如何基于条件从主XSLT映射调用多个XSLT映射?
如何基于条件从主XSLT映射调用多个XSLT映射?
你想要基于StudentClass或AGE参数的条件,从主XSLT中调用不同的XSLT映射,但当前的代码无法正常运行。
示例XML(注:原XML存在标签不匹配问题,已修正)
<?xml version="1.0" encoding="UTF-8"?> <StudentList> <Client> <Name>Jan</Name> <StudentClass>10th</StudentClass> <AGE>13</AGE> </Client> <Client> <Name>MARC</Name> <StudentClass>8th</StudentClass> <AGE>8</AGE> </Client> </StudentList>
无法运行的主XSLT代码
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" exclude-result-prefixes="#all"> <xsl:output method="xml" indent="no" omit-xml-declaration="yes"/> <xsl:param name="StudentClass" select="'10th'"/> <xsl:param name="AGE" select="'8'"/> <xsl:template match="*"> <xsl:choose> <xsl:when test="$StudentClass = '10th'"> <xsl:include href="10thClass_Mapping.xsl"/> </xsl:when> <xsl:when test="$AGE = '8'"> <xsl:include href="8years_Mapping.xsl"/> </xsl:when> </xsl:choose> </xsl:template> </xsl:stylesheet>
问题根源
<xsl:include>是编译时指令,必须在XSLT处理器编译阶段就确定要包含的文件,不能放在<xsl:choose>这种运行时的条件逻辑中,这就是当前代码无法运行的核心原因。
正确实现方案
方案1:导入所有映射,条件调用对应模板
先通过<xsl:import>或<xsl:include>导入所有需要的子XSLT文件,然后在主模板中根据条件调用对应模式的模板(假设子映射中定义了带区分模式的模板,比如10thClass_Mapping.xsl包含match="*" mode="10th"的模板,8years_Mapping.xsl包含match="*" mode="8years"的模板)。
修改后的主XSLT代码:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" exclude-result-prefixes="#all"> <xsl:output method="xml" indent="no" omit-xml-declaration="yes"/> <xsl:param name="StudentClass" select="'10th'"/> <xsl:param name="AGE" select="'8'"/> <!-- 导入所有需要的子映射 --> <xsl:import href="10thClass_Mapping.xsl"/> <xsl:import href="8years_Mapping.xsl"/> <xsl:template match="/"> <xsl:choose> <xsl:when test="$StudentClass = '10th'"> <!-- 应用10年级对应的模板逻辑 --> <xsl:apply-templates select="." mode="10th"/> </xsl:when> <xsl:when test="$AGE = '8'"> <!-- 应用8岁对应的模板逻辑 --> <xsl:apply-templates select="." mode="8years"/> </xsl:when> <xsl:otherwise> <!-- 默认处理逻辑,可根据需求调整 --> <xsl:copy-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
方案2:调用命名模板实现条件逻辑
如果子映射中定义了命名模板(比如10thClass_Mapping.xsl里有<xsl:template name="process-10th">,8years_Mapping.xsl里有<xsl:template name="process-8years">),可以直接通过条件调用这些命名模板:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" exclude-result-prefixes="#all"> <xsl:output method="xml" indent="no" omit-xml-declaration="yes"/> <xsl:param name="StudentClass" select="'10th'"/> <xsl:param name="AGE" select="'8'"/> <xsl:import href="10thClass_Mapping.xsl"/> <xsl:import href="8years_Mapping.xsl"/> <xsl:template match="/"> <xsl:choose> <xsl:when test="$StudentClass = '10th'"> <xsl:call-template name="process-10th"/> </xsl:when> <xsl:when test="$AGE = '8'"> <xsl:call-template name="process-8years"/> </xsl:when> </xsl:choose> </xsl:template> </xsl:stylesheet>
注意事项
- 建议使用模式(mode)或命名模板区分不同子映射的处理逻辑,避免模板匹配冲突。
<xsl:import>和<xsl:include>的区别:<xsl:import>导入的模板优先级低于当前样式表的模板,<xsl:include>相当于将代码直接插入当前位置,优先级与当前模板相同,可根据需求选择。
内容的提问来源于stack exchange,提问作者tkkumar8321
相关产品推荐
相关产品推荐

