XSLT 1.0转XSLT 3.0兼容改写求助:转换后功能失效
XSLT 1.0转3.0的最优实现方案
原XSLT 1.0代码核心逻辑
创建<CategoryCodes>元素并复制当前节点的所有属性,遍历<GuestRoomInfo>子节点,仅当@Code属于指定列表时,调用命名模板HotelInfo_CategoryCodes_GuestRoomInfo。
用户尝试代码的问题
- 错误使用
<xsl:copy-of select="*"/>,原逻辑是复制当前节点的属性而非子节点 - 未对
<GuestRoomInfo>添加筛选条件,导致所有节点都被处理 - 用
mode传递逻辑但未对应原命名模板的调用方式,匹配逻辑不兼容
最优实现方案(两种风格可选)
方案一:保留原命名模板,简化筛选逻辑
这种方式完全兼容原代码的模板调用逻辑,同时利用XSLT3.0的集合判断简化代码:
<!-- 定义可复用的允许Code列表,便于后续维护 --> <xsl:variable name="selectedCodes" select="(3, 5, 6, 10, 12, 13, 19, 24, 26, 28, 47)"/> <xsl:template match="*" name="GenerateCategoryCodes"> <xsl:element name="CategoryCodes"> <!-- 复制当前节点的所有属性 --> <xsl:copy-of select="@*"/> <!-- 直接筛选符合条件的GuestRoomInfo并调用模板 --> <xsl:for-each select="GuestRoomInfo[@Code = $selectedCodes]"> <xsl:call-template name="HotelInfo_CategoryCodes_GuestRoomInfo"/> </xsl:for-each> </xsl:element> </xsl:template>
方案二:改用XSLT3.0模式匹配(声明式风格)
如果希望更贴合XSLT3.0的最佳实践,可以将原命名模板改为模式匹配模板,代码更具扩展性:
<xsl:variable name="selectedCodes" select="(3, 5, 6, 10, 12, 13, 19, 24, 26, 28, 47)"/> <!-- 主模板:生成CategoryCodes结构 --> <xsl:template match="*" name="CategoryCodes"> <xsl:element name="CategoryCodes"> <xsl:copy-of select="@*"/> <!-- 对符合条件的GuestRoomInfo应用指定模式的处理逻辑 --> <xsl:apply-templates select="GuestRoomInfo[@Code = $selectedCodes]" mode="process-room"/> </xsl:element> </xsl:template> <!-- 模式模板:替代原命名模板处理符合条件的GuestRoomInfo --> <xsl:template match="GuestRoomInfo" mode="process-room"> <!-- 此处直接编写原HotelInfo_CategoryCodes_GuestRoomInfo模板的逻辑, 或者保留原模板并通过<xsl:call-template>调用 --> <xsl:call-template name="HotelInfo_CategoryCodes_GuestRoomInfo"/> </xsl:template>
优化说明
- 用变量统一管理允许的Code值,避免重复代码,修改更便捷
- 直接通过
[@Code = $selectedCodes]筛选节点,替代原冗长的<xsl:choose>判断,代码更简洁可读 - 两种方案均严格对齐原XSLT1.0的业务逻辑,同时充分利用XSLT3.0的语法特性
内容的提问来源于stack exchange,提问作者Srikar Gunna
相关产品推荐
相关产品推荐

