XSL模板匹配中使用变量替换${para1}的失效问题
问题解决:XSLT中使用变量匹配带大括号的文本节点
问题描述
需要为XML中包含w:t="${para1}"的<w:p>标签添加属性,硬编码para1时匹配正常,但将para1定义为变量$variable后,尝试以下三种方式均无法生效:
${$variable}- 定义左右大括号变量后拼接(
concat($left,$variable,$right)) - 双层大括号
${{$variable}}
相关XML示例:
<?xml version="1.0"?> <w:document xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006"> <w:body> <w:p> <w:r> <w:t>${para1}</w:t> </w:r> </w:p> </w:body> </w:document>
原XSL代码(存在变量匹配问题):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" > <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:variable name="variable">para1</xsl:variable> <xsl:variable name="attribute_id">1</xsl:variable> <xsl:template match='w:p[w:r/w:t="${para1}"]'> <!--<xsl:variable name="left">${</xsl:variable> <xsl:variable name="right">}</xsl:variable> <xsl:template match='w:p[w:r/w:t="concat($left,$variable,$right)"]'>--> <!--<xsl:template match='w:p[w:r/w:t="${$variable}"]'>--><!--para1 should be variable--> <xsl:copy> <xsl:attribute name="w:id"> <xsl:value-of select="$attribute_id" /></xsl:attribute> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
原因分析
XSLT 1.0的模板匹配模式是静态字符串,无法直接在匹配模式中插入变量进行动态拼接。之前的写法都是试图在静态匹配字符串中嵌入变量,这不符合XSLT的语法规则。
解决方案
在模板匹配的谓词中,使用concat()函数动态构造目标匹配字符串,再与w:t的文本内容进行比较:
修改后的XSL代码:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" > <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:variable name="variable">para1</xsl:variable> <xsl:variable name="attribute_id">1</xsl:variable> <!-- 使用concat构造目标字符串,实现动态匹配 --> <xsl:template match='w:p[w:r/w:t = concat("${", $variable, "}")]'> <xsl:copy> <xsl:attribute name="w:id"> <xsl:value-of select="$attribute_id" /> </xsl:attribute> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
说明
concat("${", $variable, "}")会动态生成${para1}字符串,和XML中w:t的文本内容完全匹配- 这种方式利用了XSLT谓词中的表达式计算能力,绕过了静态匹配模式的限制,实现了变量驱动的动态匹配
内容的提问来源于stack exchange,提问作者Premlatha
相关产品推荐
相关产品推荐

