XSLT中变量通过<xsl:variable>声明,可使用select属性或元素内容赋值,支持XPath复杂计算,变量一旦赋值不可更改,分全局和局部两种作用域,全局变量在<xsl:stylesheet>下声明并全局可用,局部变量在模板等元素内声明仅限局部使用,引用时用$前缀;参数<xsl:param>用于接收外部传入值,具默认值机制,与变量主要区别在于来源和用途。

XSLT中声明变量,核心在于使用
<xsl:variable>
$
在XSLT中,变量的声明和使用其实比很多人想象的要直接,但也带有一些独特的“XSLT哲学”。我们主要通过
<xsl:variable>
首先,声明一个变量有两种基本形式:
带select
<xsl:variable name="myVariable" select="root/element/value"/> <xsl:variable name="calculatedPrice" select="@quantity * @unitPrice"/>
这里,
myVariable
root/element/value
calculatedPrice
作为元素内容:当变量的值不是一个简单的XPath表达式结果,或者你想存储一个节点集(而非其字符串值)时,你可以将内容放在
<xsl:variable>
<xsl:variable name="greeting">Hello, World!</xsl:variable>
<xsl:variable name="importantNodes">
<xsl:copy-of select="items/item[position() <= 3]"/>
</xsl:variable>在第一个例子中,
greeting
importantNodes
item
关于作用域: 如果你在
<xsl:stylesheet>
<xsl:template>
<xsl:for-each>
<xsl:if>
关于引用: 无论全局还是局部,引用变量都非常简单,只需要在变量名前加上
$
<xsl:value-of select="$myVariable"/> <xsl:value-of select="$calculatedPrice * 1.1"/> <!-- 加上10%的税 -->
一个核心概念是,XSLT变量一旦声明并赋值,就不能再被重新赋值。它们是“单次赋值”的,这和很多编程语言中可变变量的概念很不一样。这有时会让初学者感到困惑,但它也反映了XSLT的函数式编程思想,使得转换过程更具确定性。
这个问题我常常会遇到,很多人一开始都会把变量和参数混淆,或者不清楚何时该用哪个。在我看来,理解它们的核心区别在于“来源”和“目的”。
XSLT变量 (<xsl:variable>
XSLT参数 (<xsl:param>
reportTitle
currencySymbol
语法上的区别:
<xsl:variable name="varName" select="value"/>
<xsl:param name="paramName" select="defaultValue"/>
select
使用场景: 假设你要生成一份发票。
itemTotal = @quantity * @price
invoiceTotal = sum($itemTotals)
customerName
invoiceDate
所以,简单来说,变量是“我自己的内部工具”,而参数是“别人给我用的外部输入”。两者在一旦赋值后都是不可变的,这是它们的共同点。
变量的声明位置对它的可见范围,也就是“作用域”,有着决定性的影响。这和很多编程语言中的变量作用域规则类似,但XSLT有其自身的特点。
全局变量 (Top-level Variables) 当你在
<xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="companyName" select="'Acme Corp.'"/>
<xsl:template match="/">
<!-- 这里可以访问 $companyName -->
<report>
<title><xsl:value-of select="$companyName"/> Report</title>
<xsl:apply-templates select="data"/>
</report>
</xsl:template>
<xsl:template match="data">
<!-- 这里也可以访问 $companyName -->
<section><xsl:value-of select="$companyName"/> Data Section</section>
</xsl:template>
</xsl:stylesheet>全局变量的特点是:
select
局部变量 (Local Variables) 当你在
<xsl:template>
<xsl:for-each>
<xsl:if>
<xsl:choose>
<xsl:template match="item">
<xsl:variable name="itemTotal" select="@quantity * @price"/>
<product>
<name><xsl:value-of select="name"/></name>
<total><xsl:value-of select="$itemTotal"/></total>
</product>
<xsl:if test="$itemTotal > 100">
<discount eligible="true"/>
</xsl:if>
<!-- 在这里可以访问 $itemTotal -->
</xsl:template>
<xsl:template match="order">
<!-- 这里无法访问 $itemTotal,因为它在 'item' 模板内部声明 -->
<orderSummary>...</orderSummary>
</xsl:template>局部变量的特点是:
select
item
itemTotal
item
作用域的层级关系: XSLT的作用域是嵌套的。一个内层作用域可以访问所有外层作用域的变量。如果内层作用域声明了一个与外层作用域同名的变量,那么内层作用域的变量会“遮蔽”外层作用域的同名变量。这意味着在内层作用域中,你将访问到的是新声明的变量,而不是外层的那个。这在实际开发中需要留意,避免意外的行为。
选择全局还是局部,通常取决于变量的用途和生命周期。如果一个值是整个样式表通用的,并且只计算一次,那么全局变量是合适的。如果一个值只在特定处理逻辑中需要,并且可能依赖于当前上下文,那么局部变量更佳,它能保持代码的封装性和清晰性。
XSLT变量的真正威力,很大程度上体现在它与XPath表达式的结合上。
select
举几个例子来具体说明:
从复杂结构中提取并组合数据 假设你的XML输入是这样的:
<invoice>
<customer id="C001">
<firstName>John</firstName>
<lastName>Doe</lastName>
</customer>
<items>
<item id="I001" quantity="2" price="10.50"/>
<item id="I002" quantity="1" price="25.00"/>
</items>
</invoice>你可以用变量来构建客户的全名:
<xsl:variable name="customerFullName" select="invoice/customer/firstName || ' ' || invoice/customer/lastName"/> <!-- 引用:<xsl:value-of select="$customerFullName"/> -->
这里使用了XPath 2.0的字符串连接操作符
||
concat()
select="concat(invoice/customer/firstName, ' ', invoice/customer/lastName)"
进行聚合计算 要计算所有商品的总价,你可以这样做:
<xsl:variable name="totalAmount" select="sum(invoice/items/item/@quantity * invoice/items/item/@price)"/> <!-- 引用:<xsl:value-of select="$totalAmount"/> -->
sum()
item
quantity
price
item
存储过滤后的节点集 有时你可能需要先筛选出一部分节点,然后对这部分节点进行多次操作。将它们存储在变量中可以提高可读性和效率。
<xsl:variable name="highValueItems" select="invoice/items/item[@price > 20]"/>
<!-- 之后可以对 $highValueItems 进行处理 -->
<xsl:for-each select="$highValueItems">
<highValueProduct id="{@id}" total="{@quantity * @price}"/>
</xsl:for-each>highValueItems
item
条件逻辑(XSLT 2.0+) XSLT 2.0及更高版本引入了XPath 2.0,这使得在
select
<xsl:variable name="statusMessage" select="if (invoice/totalAmount > 1000) then 'High Value Invoice' else 'Standard Invoice'"/> <!-- 引用:<xsl:value-of select="$statusMessage"/> -->
这比在XSLT 1.0中用
<xsl:choose>
<xsl:if>
这些例子都展现了XSLT变量在结合XPath表达式时的强大之处。它允许你将复杂的业务逻辑和数据处理步骤封装起来,让样式表结构更清晰,逻辑更易于理解和维护。我个人在处理复杂数据转换时,就非常依赖这种方式来分解问题,将每一步的中间结果存储起来,再逐步构建最终的输出。
以上就是XSLT变量如何声明使用?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号