在XSL的XPath中使用参数值替换文本失败的问题排查
问题:XSL中使用参数匹配XPath未生效,文本替换失败
需要在XSL的match语句对应的XPath中使用参数值,匹配指定<w:p>节点并替换其下<w:t>的文本内容,但替换操作未生效。期望将<w:t>value1</w:t>替换为<w:t>new value</w:t>。
原XML代码
<?xml version="1.0"?> <w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"> <w:body> <w:p w:id="1" w:rsidR="00041C05" w:rsidRDefault="00EA4F36"> <w:r> <w:t>value1</w:t> </w:r> </w:p> <w:sectPr w:rsidR="00041C05" w:rsidSect="00041C05"> <w:pgSz w:w="12240" w:h="15840"/> <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/> <w:cols w:space="720"/> <w:docGrid w:linePitch="360"/> </w:sectPr> </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" exclude-result-prefixes="w" > <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:param name="replacement"> new value </xsl:param> <xsl:param name="id">1</xsl:param> <xsl:template match='w:p[@w:id="$id"]/w:r/w:t/text()'> <xsl:value-of select="$replacement" /> </xsl:template> </xsl:stylesheet>
当前输出
<?xml version="1.0" encoding="UTF-8"?><w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"> <w:body> <w:p w:id="1" w:rsidR="00041C05" w:rsidRDefault="00EA4F36"> <w:r> <w:t>value1</w:t> </w:r> </w:p> <w:sectPr w:rsidR="00041C05" w:rsidSect="00041C05"> <w:pgSz w:w="12240" w:h="15840"/> <w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="720" w:footer="720" w:gutter="0"/> <w:cols w:space="720"/> <w:docGrid w:linePitch="360"/> </w:sectPr> </w:body> </w:document>
问题原因
核心错误在于match模式的XPath写法:w:p[@w:id="$id"]中,"$id"是字符串字面量,会尝试匹配w:id属性值为$id的节点,而非匹配属性值等于参数$id值的节点。XPath中引用变量时不能将变量放在引号内,需要直接用变量与属性值做比较。
另外,参数$replacement的定义包含换行和缩进空格,会导致输出的文本带有多余空白,需要优化。
解决方案
修改match语句的XPath,将属性匹配逻辑改为@w:id = $id,同时调整$replacement参数的写法以避免多余空白:
<?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" exclude-result-prefixes="w" > <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()" /> </xsl:copy> </xsl:template> <xsl:param name="replacement">new value</xsl:param> <xsl:param name="id">1</xsl:param> <xsl:template match='w:p[@w:id = $id]/w:r/w:t/text()'> <xsl:value-of select="$replacement" /> </xsl:template> </xsl:stylesheet>
修改后,XPath会正确匹配w:id属性值等于参数$id的<w:p>节点,其下的<w:t>文本会被替换为$replacement的值,得到期望的输出。
内容的提问来源于stack exchange,提问作者Premlatha
相关产品推荐
相关产品推荐

