能否在XSLT的if语句中嵌套模板?场景需求求解
问题解决:基于条件修改XML节点值
原始XML结构
<Requirement> <Name code="001">Hello</Name> <Day>Monday</Day> <Status>Open</Status> . . . --- ALOT OF OTHER DATA --- </Requirement>
现有XSLT代码
. . <xsl:template match="/"> <xml> <ID> <xsl:value-of select="/Requirement/Name/text()" /> </ID> <xsl:apply-templates select="@*|node()" /> </xml> </xsl:template> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> . .
需求说明
- 保留现有的身份模板(即
match="@*|node()"的复制模板) - 当
<Name>的文本值为Hello,且<Status>的文本值为Open时,把<Day>的内容改成Friday - 如果
<Name>的值不是Hello,则完全保留原始XML结构,不做修改
你之前尝试的嵌套写法行不通,代码如下:
<xsl:if test="Name='Hello'"> <xsl:template match="Day/text()"> <xsl:value-of select="Friday" /> </xsl:template> </xsl:if>
可行实现方案
XSLT是声明式语言,模板不能嵌套在<xsl:if>这类流程控制标签里。正确的做法是给模板添加匹配条件,利用模板优先级来覆盖默认的身份模板。
完整XSLT代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <xml> <ID> <xsl:value-of select="/Requirement/Name/text()" /> </ID> <xsl:apply-templates select="@*|node()" /> </xml> </xsl:template> <!-- 保留原始的身份模板 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 新增条件匹配的模板:仅当Requirement下Name为Hello且Status为Open时,修改Day的内容 --> <xsl:template match="Requirement[Name='Hello' and Status='Open']/Day"> <Day>Friday</Day> </xsl:template> </xsl:stylesheet>
代码说明
- 保留了你原有的根模板和身份模板,确保大部分节点都能被原样复制
- 新增的模板
match="Requirement[Name='Hello' and Status='Open']/Day"会优先匹配符合条件的<Day>节点:- 只有当父节点
<Requirement>下的<Name>是Hello,且<Status>是Open时,这个模板才会生效 - 生效时直接输出
<Day>Friday</Day>,替换原有的<Day>节点内容
- 只有当父节点
- 不符合条件的
<Day>节点(比如Name不是Hello,或者Status不是Open),会继续使用原始的身份模板原样复制
这样就完全满足你的需求,同时保留了原有的复制逻辑。
内容的提问来源于stack exchange,提问作者Hannah
相关产品推荐
相关产品推荐

