XSLT的xsl:param元素用于在样式表中定义参数,通过这些参数可以在执行XML转换时传入动态值,让样式表的转换逻辑更灵活,不需要每次修改样式表本身就能适配不同的转换需求。

xsl:param的基本语法
xsl:param有两种使用场景,分别是定义全局参数和定义模板内的局部参数,基本语法格式如下:
<xsl:param name="参数名称" select="默认值"/>
其中name属性是必填项,用于指定参数的唯一标识;select属性是可选的,用于设置参数的默认值,如果没有传入对应参数,就会使用默认值参与转换逻辑。
全局参数定义
全局参数需要定义在样式表的顶层,也就是<xsl:stylesheet>标签的直接子元素位置,所有模板都可以访问这个参数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- 定义全局参数,默认值为普通用户 -->
<xsl:param name="user_type" select="'普通用户'"/>
<xsl:template match="/">
<p>当前用户类型:<xsl:value-of select="$user_type"/></p>
</xsl:template>
</xsl:stylesheet>
局部参数定义
局部参数定义在某个<xsl:template>模板内部,只有当前模板可以访问,不会影响其他模板的逻辑:
<xsl:template match="user">
<!-- 定义局部参数,默认值为未知 -->
<xsl:param name="show_status" select="'未知'"/>
<p>用户:<xsl:value-of select="name"/>,状态:<xsl:value-of select="$show_status"/></p>
</xsl:template>
向样式表传递参数的两种方式
方式一:在XSLT内部直接传入参数
如果是在XSLT样式表内部调用模板时传递参数,可以使用<xsl:with-param>元素,需要和<xsl:apply-templates>或者<xsl:call-template>配合使用:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:apply-templates select="users/user">
<!-- 向模板传递参数 -->
<xsl:with-param name="show_status" select="'活跃'"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="user">
<xsl:param name="show_status" select="'未知'"/>
<p>用户:<xsl:value-of select="name"/>,状态:<xsl:value-of select="$show_status"/></p>
</xsl:template>
</xsl:stylesheet>
方式二:在外部调用时传入参数
如果是通过外部程序调用XSLT转换,比如使用Java、Python等语言的XSLT处理库,可以在调用时传入参数,这里以Python的lxml库为例:
首先准备待转换的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<users>
<user>
<name>张三</name>
</user>
<user>
<name>李四</name>
</user>
</users>
然后是XSLT样式表,定义全局参数:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="title" select="'用户列表'"/>
<xsl:template match="/">
<html>
<body>
<h1><xsl:value-of select="$title"/></h1>
<ul>
<xsl:apply-templates select="users/user"/>
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="user">
<li><xsl:value-of select="name"/></li>
</xsl:template>
</xsl:stylesheet>
Python调用代码,传入参数:
from lxml import etree
# 加载XML和XSLT
xml_doc = etree.parse("test.xml")
xslt_doc = etree.parse("test.xsl")
transform = etree.XSLT(xslt_doc)
# 传入参数,参数名要和xsl:param的name一致
result = transform(xml_doc, title=etree.XSLT.strparam("当前活跃用户"))
print(str(result))
注意事项
- 参数名区分大小写,传递参数时名称必须和xsl:param定义的name完全一致。
- 如果定义了局部参数,同时用xsl:with-param传入了同名参数,会优先使用传入的参数值,忽略默认值。
- 参数值可以是字符串、数字、节点集等XSLT支持的数据类型,根据select属性的表达式决定类型。
- 在XSLT中引用参数时,需要在参数名前加$符号,比如$user_type。