如何在XSLT复制XML时用last-token模板结果修改指定属性值?
问题解决:提取XML路径中的文件名并替换属性值
你的核心问题是调用命名模板的方式错误,加上未传递必要参数,导致结果为空。具体问题和修正方案如下:
问题点
- 调用模板的方式不对:
last-token是命名模板,不是XML节点,不能用<xsl:apply-templates select="last-token"/>,得用<xsl:call-template name="last-token"/>来调用。 - 没传参数:
last-token需要接收原路径值作为text参数,你没传,模板处理空值自然返回空。 - 模板逻辑冗余:匹配
@Value的模板里,先输出$result再生成新属性,会导致输出异常,应该直接生成新属性覆盖原属性。
修正后的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="Field[@Type='DD_FilePath']/@Value"> <xsl:variable name="result"> <!-- 调用命名模板并传递当前属性值作为text参数 --> <xsl:call-template name="last-token"> <xsl:with-param name="text" select="."/> </xsl:call-template> </xsl:variable> <!-- 生成新的Value属性,覆盖原属性 --> <xsl:attribute name="Value"> <xsl:value-of select="$result"/> </xsl:attribute> </xsl:template> <xsl:template name="last-token"> <xsl:param name="text"/> <xsl:param name="delimiter" select="'\'"/> <xsl:choose> <xsl:when test="contains($text, $delimiter)"> <xsl:call-template name="last-token"> <xsl:with-param name="text" select="substring-after($text, $delimiter)"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-of select="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template> </xsl:stylesheet>
关键修改说明
- 用
<xsl:call-template name="last-token"/>替代<xsl:apply-templates select="last-token"/>,并通过<xsl:with-param name="text" select="."/>把当前Value属性的路径值传给模板。 - 移除了多余的
<xsl:value-of select="$result"/>,避免输出重复内容。
用这个XSLT处理你的XML,就能得到你期望的结果:只修改DD_FilePath对应的Value为路径最后一个反斜杠后的文件名,其他属性保持不变。
内容的提问来源于stack exchange,提问作者SAM
相关产品推荐
相关产品推荐

