XSLT开发时如何仅修改nodeset内单个字段且保留其余全部数据
解决方案
核心逻辑
XSLT中节点为不可变类型,无法直接修改原有节点集的字段值,需要通过递归复制原有全部节点,仅对目标字段做特殊改写,最终生成修改后的新节点集使用。
实现步骤
1. 声明EXSLT命名空间(XSLT 1.0 环境必须,Symphony CMS默认支持)
在你的XSLT文件根节点<xsl:stylesheet>上添加以下属性,用于支持结果树片段转节点集:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">
2. 定义节点复制与修改模板
新增modify-price专属模式的模板,避免和你现有模板逻辑冲突:
<!-- 身份模板:递归复制所有节点、属性,保持原有结构完全不变 --> <xsl:template match="@*|node()" mode="modify-price"> <xsl:copy> <xsl:apply-templates select="@*|node()" mode="modify-price" /> </xsl:copy> </xsl:template> <!-- 仅匹配price字段,修改值为原数值减1 --> <xsl:template match="entry/price" mode="modify-price"> <xsl:copy> <xsl:value-of select=". - 1" /> </xsl:copy> </xsl:template>
3. 生成修改后的节点集
定义变量存储修改后的完整menu-dish节点集:
<!-- 生成修改后的结果树片段 --> <xsl:variable name="modified-menu-dish-rtf"> <xsl:apply-templates select="menu-dish" mode="modify-price" /> </xsl:variable> <!-- XSLT 1.0 转成可直接操作的节点集,XSLT 2.0+可跳过这一步直接使用上面的变量 --> <xsl:variable name="modified-menu-dish" select="exsl:node-set($modified-menu-dish-rtf)/menu-dish" />
4. 调用原有渲染模板
将修改后的节点集传入原有模板即可:
<xsl:apply-templates select="$modified-menu-dish" mode="menu_dish_information"/>
注意事项
- 该方案会保留
menu-dish下所有原有结构、属性、子节点,仅修改entry下的price字段值 - 如果你的环境支持XSLT 2.0及以上版本,无需引入EXSLT命名空间,也不需要做
exsl:node-set转换,直接使用$modified-menu-dish-rtf即可 modify-price模式名可以自定义,只要和你现有模板的mode不冲突即可
内容的提问来源于stack exchange,提问作者Bogdan Onyshenko
相关产品推荐
相关产品推荐

