XSLT-if详解:条件判断的语法与实战
2026/9/7 9:39:51 网站建设 项目流程

1. 引言

XSLT(可扩展样式表语言转换)是处理 XML 文档的强大工具,而<xsl:if>是其中最常用的条件判断指令之一。它允许我们在转换过程中根据节点内容、属性值或表达式结果,有选择地输出内容。本文将通过丰富的代码实例,深入讲解<xsl:if>的语法、用法、常见陷阱以及与其他条件指令的对比。

2. 基础语法

<xsl:if>的语法非常简单,核心是test属性,它接受一个 XPath 表达式。当表达式的结果为真(true)时,元素内部的内容会被输出;否则被忽略。

<xsl:if test="条件表达式"> <!-- 当条件为真时输出的内容 --> </xsl:if>

下面是一个最基础的示例。假设我们有如下 XML 数据:

<?xml version="1.0" encoding="UTF-8"?> <books> <book> <title>XML 入门</title> <price>59.00</price> </book> <book> <title>XSLT 高级编程</title> <price>89.00</price> </book> </books>

我们希望只输出价格大于 60 元的书籍:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <body> <h2>高价书籍列表</h2> <xsl:for-each select="books/book"> <xsl:if test="price > 60"> <p> <xsl:value-of select="title"/> —— 价格:<xsl:value-of select="price"/> 元 </p> </xsl:if> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

运行结果:

<html> <body> <h2>高价书籍列表</h2> <p>XSLT 高级编程 —— 价格:89.00 元</p> </body> </html>

注意:在 XSLT 1.0 中,>需要写成&gt;<需要写成&lt;,以避免与 XML 标签冲突。

3. 常用条件表达式

<xsl:if>test属性支持丰富的 XPath 表达式。下面分类介绍最常见的几种。

3.1 比较运算

数值和字符串比较是最基础的条件判断。

<!-- 数值比较 --> <xsl:if test="price > 100">高价书</xsl:if> <xsl:if test="price <= 50">低价书</xsl:if> <xsl:if test="price = 59.00">价格正好是 59 元</xsl:if> <!-- 字符串比较 --> <xsl:if test="title = 'XML 入门'">找到入门书</xsl:if> <xsl:if test="title != 'XSLT 高级编程'">不是高级编程书</xsl:if>

3.2 逻辑运算

使用andornot()可以组合多个条件。

<!-- 与:价格在 50 到 100 之间 --> <xsl:if test="price >= 50 and price <= 100"> 中等价位书籍 </xsl:if> <!-- 或:作者是张三或李四 --> <xsl:if test="author = '张三' or author = '李四'"> 目标作者的作品 </xsl:if> <!-- 非:不是绝版书 --> <xsl:if test="not(@status = 'out_of_print')"> 在售书籍 </xsl:if>

3.3 节点存在性判断

判断某个子元素或属性是否存在,是实际开发中非常常见的需求。

<!-- 判断子元素是否存在 --> <xsl:if test="publisher"> 有出版社信息:<xsl:value-of select="publisher"/> </xsl:if> <!-- 判断属性是否存在 --> <xsl:if test="@isbn"> ISBN:<xsl:value-of select="@isbn"/> </xsl:if> <!-- 判断节点集合是否为空 --> <xsl:if test="not(comments/comment)"> 暂无评论 </xsl:if>

3.4 字符串函数

XPath 提供了丰富的字符串处理函数,可以用于更复杂的条件判断。

<!-- 判断字符串长度 --> <xsl:if test="string-length(title) > 10"> 标题较长 </xsl:if> <!-- 判断是否以某字符串开头 --> <xsl:if test="starts-with(title, 'XML')"> 标题以 XML 开头 </xsl:if> <!-- 判断是否包含某字符串 --> <xsl:if test="contains(description, '实战')"> 包含"实战"关键词 </xsl:if>

4. 实战案例:图书目录转换

下面通过一个完整的实战案例,综合运用<xsl:if>的各种用法。假设我们要将一份图书 XML 转换为带分类标记的 HTML 页面。

<?xml version="1.0" encoding="UTF-8"?> <library> <book category="programming"> <title>XSLT 2.0 权威指南</title> <author>Michael Kay</author> <price currency="CNY">128.00</price> <stock>25</stock> </book> <book category="database"> <title>SQL 必知必会</title> <author>Ben Forta</author> <price currency="CNY">49.00</price> <stock>0</stock> </book> <book category="programming"> <title>深入理解计算机系统</title> <author>Randal E. Bryant</author> <price currency="CNY">139.00</price> <stock>8</stock> </book> </library>

对应的 XSLT 样式表:

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <html> <head> <title>图书馆藏书</title> </head> <body> <h1>图书馆藏书目录</h1> <xsl:for-each select="library/book"> <div style="border:1px solid #ccc; margin:10px; padding:10px;"> <h3><xsl:value-of select="title"/></h3> <p>作者:<xsl:value-of select="author"/></p> <p>价格:<xsl:value-of select="price"/> 元</p> <!-- 分类标记 --> <xsl:if test="@category = 'programming'"> <p style="color:blue;">分类:编程技术</p> </xsl:if> <xsl:if test="@category = 'database'"> <p style="color:green;">分类:数据库</p> </xsl:if> <!-- 库存状态提示 --> <xsl:if test="stock = 0"> <p style="color:red;">暂时缺货</p> </xsl:if> <xsl:if test="stock > 0 and stock < 10"> <p style="color:orange;">库存紧张,仅剩 <xsl:value-of select="stock"/> 本</p> </xsl:if> <xsl:if test="stock >= 10"> <p style="color:green;">库存充足</p> </xsl:if> <!-- 价格区间提示 --> <xsl:if test="price > 100"> <p>这是一本高价技术书籍</p> </xsl:if> </div> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet>

输出结果:

<html> <head> <title>图书馆藏书</title> </head> <body> <h1>图书馆藏书目录</h1> <div style="border:1px solid #ccc; margin:10px; padding:10px;"> <h3>XSLT 2.0 权威指南</h3> <p>作者:Michael Kay</p> <p>价格:128.00 元</p> <p style="color:blue;">分类:编程技术</p> <p style="color:green;">库存充足</p> <p>这是一本高价技术书籍</p> </div> <div style="border:1px solid #ccc; margin:10px; padding:10px;"> <h3>SQL 必知必会</h3> <p>作者:Ben Forta</p> <p>价格:49.00 元</p> <p style="color:green;">分类:数据库</p> <p style="color:red;">暂时缺货</p> </div> <div style="border:1px solid #ccc; margin:10px; padding:10px;"> <h3>深入理解计算机系统</h3> <p>作者:Randal E. Bryant</p> <p>价格:139.00 元</p> <p style="color:blue;">分类:编程技术</p> <p style="color:orange;">库存紧张,仅剩 8 本</p> <p>这是一本高价技术书籍</p> </div> </body> </html>

5. 嵌套使用

<xsl:if>支持嵌套,可以在一个条件内部再判断其他条件,实现更复杂的逻辑。

<xsl:for-each select="library/book"> <xsl:if test="@category = 'programming'"> <xsl:if test="price > 100"> <p>高价编程书:<xsl:value-of select="title"/></p> </xsl:if> <xsl:if test="price <= 100"> <p>平价编程书:<xsl:value-of select="title"/></p> </xsl:if> </xsl:if> </xsl:for-each>

虽然嵌套可以实现多分支逻辑,但当分支较多时,代码会变得难以阅读。此时建议使用<xsl:choose>配合<xsl:when><xsl:otherwise>,结构更清晰。

6. 与 xsl:choose 的对比

<xsl:if>只有"真"和"假"两个分支,且没有"否则"(else)的概念。当需要多分支或默认分支时,应使用<xsl:choose>

<!-- 使用 xsl:if 实现多分支(代码冗余) --> <xsl:if test="score >= 90">优秀</xsl:if> <xsl:if test="score >= 80 and score < 90">良好</xsl:if> <xsl:if test="score >= 60 and score < 80">及格</xsl:if> <xsl:if test="score < 60">不及格</xsl:if> <!-- 使用 xsl:choose 实现同样逻辑(更清晰) --> <xsl:choose> <xsl:when test="score >= 90">优秀</xsl:when> <xsl:when test="score >= 80">良好</xsl:when> <xsl:when test="score >= 60">及格</xsl:when> <xsl:otherwise>不及格</xsl:otherwise> </xsl:choose>

选择建议:

  • 只有单一条件判断时,使用<xsl:if>更简洁。
  • 需要"否则"分支或多条件互斥时,使用<xsl:choose>更合适。
  • 多个独立条件需要分别判断时,可以连续使用多个<xsl:if>

7. 常见陷阱与注意事项

在实际开发中,<xsl:if>有几个容易踩坑的地方,需要特别注意。

7.1 布尔值转换

XPath 中,空节点集、空字符串、数字 0 和 NaN 都会被转换为 false,其他值转换为 true。这可能导致意想不到的结果。

<!-- 陷阱:price 为 0 时,条件为 false --> <xsl:if test="price"> 价格存在且不为 0 </xsl:if> <!-- 正确做法:显式判断节点是否存在 --> <xsl:if test="price != ''"> 价格节点存在 </xsl:if>

7.2 字符串比较的引号问题

在 XML 属性中,字符串值通常使用单引号包裹,避免与属性值的双引号冲突。

<!-- 正确:外层双引号,内层单引号 --> <xsl:if test="title = 'XML 入门'">...</xsl:if> <!-- 错误:内外都是双引号,会导致解析错误 --> <!-- <xsl:if test="title = "XML 入门"">...</xsl:if> -->

7.3 大小写敏感

XPath 的字符串比较是大小写敏感的。如果需要忽略大小写,可以使用translate()函数转换。

<!-- 大小写敏感 --> <xsl:if test="category = 'Programming'">...</xsl:if> <!-- 忽略大小写比较 --> <xsl:if test="translate(category, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') = 'programming'"> 编程类书籍(不区分大小写) </xsl:if>

7.4 空白字符处理

XML 中的空白字符可能导致字符串比较失败。使用normalize-space()函数可以去除首尾空白并合并连续空白。

<!-- 假设 category 的值为 " programming "(带空格) --> <xsl:if test="normalize-space(category) = 'programming'"> 编程类书籍 </xsl:if>

8. XSLT 2.0 中的增强

XSLT 2.0 对条件判断做了一些增强,最显著的是支持if...then...else表达式,可以直接在 XPath 中使用。

<!-- XSLT 2.0 的 if-then-else 表达式 --> <xsl:value-of select="if (price > 100) then '高价' else '平价'"/> <!-- 也可以嵌套使用 --> <xsl:value-of select="if (price > 100) then '高价' else if (price > 50) then '中等' else '低价'"/>

此外,XSLT 2.0 还支持在<xsl:if>中使用更丰富的 XPath 2.0 函数,如matches()正则匹配、ends-with()等。

<!-- XSLT 2.0 正则匹配 --> <xsl:if test="matches(title, '^XSLT')"> 标题以 XSLT 开头 </xsl:if> <!-- XSLT 2.0 结尾判断 --> <xsl:if test="ends-with(title, '指南')"> 标题以"指南"结尾 </xsl:if>

9. 总结

<xsl:if>是 XSLT 中最基础也最常用的条件判断指令。通过本文的实例,我们掌握了它的核心语法、常用表达式、嵌套用法以及与<xsl:choose>的对比。在实际开发中,建议根据场景选择合适的条件指令:单一条件用<xsl:if>,多分支互斥用<xsl:choose>,XSLT 2.0 环境下还可以使用内联的if-then-else表达式。同时要注意布尔值转换、引号、大小写和空白字符等常见陷阱,写出健壮可靠的样式表。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询