向XSLT 2.0脚本传递字符串参数失败,整数参数可正常使用
lxml调用XSLT 2.0时字符串参数无法传递的问题解决
问题现象
使用lxml调用XSLT 2.0脚本时,整数参数可通过$my_param正常访问,但传递字符串参数(如"value"、"w1234")时,XSLT中无法获取到参数值,输出为空节点。
相关代码
Python代码:
from lxml import etree xml_doc = etree.parse('input.xml') xslt_doc = etree.parse('my_stylesheet.xslt') transform = etree.XSLT(xslt_doc) result_tree = transform(xml_doc, my_param='value') result_tree.write('output.xml', pretty_print=True)
XSLT样式表:
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <root> <param><xsl:value-of select="$my_param"/></param> </root> </xsl:template> </xsl:stylesheet>
输入XML:
<?xml version="1.0" encoding="utf-8"?> <root> <data /> </root>
预期输出:
<root> <param>value</param> </root>
实际输出:
<root> <param/> </root>
问题原因
lxml在向XSLT传递参数时,若未显式指定参数类型,会默认将参数值当作XPath表达式解析。对于字符串(如"value"),lxml会尝试在XML文档中查找匹配value的节点,找不到则返回空;而整数会被直接识别为数值类型,不会触发XPath解析,因此能正常传递。
解决方法
有两种可靠的解决方式:
方法1:使用etree.XSLT.strparam()包装字符串参数
在Python代码中,用strparam()明确标记参数为字符串字面量,避免lxml将其解析为XPath表达式:
from lxml import etree xml_doc = etree.parse('input.xml') xslt_doc = etree.parse('my_stylesheet.xslt') transform = etree.XSLT(xslt_doc) # 用strparam包装字符串参数 result_tree = transform(xml_doc, my_param=etree.XSLT.strparam('value')) result_tree.write('output.xml', pretty_print=True)
方法2:在XSLT中显式声明参数类型
在XSLT样式表中添加<xsl:param>节点,指定参数的类型为xs:string,强制XSLT将传入的参数转换为字符串类型(需引入XML Schema命名空间):
<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xsl:output method="xml" indent="yes"/> <!-- 显式声明参数类型为字符串 --> <xsl:param name="my_param" as="xs:string"/> <xsl:template match="/"> <root> <param><xsl:value-of select="$my_param"/></param> </root> </xsl:template> </xsl:stylesheet>
修改后,原Python代码无需改动即可正常传递字符串参数。
验证结果
两种方法都能让XSLT正确获取到字符串参数值,输出符合预期的XML内容。
内容的提问来源于stack exchange,提问作者Boris Hoeller
相关产品推荐
相关产品推荐

