Skip to content

20 附录 C:标记选择器语法

Thymeleaf 的标记选择器(Markup Selectors)直接沿用自其底层解析库: AttoParser

该选择器的语法与 XPath、CSS 及 jQuery 的选择器高度相似,因此大多数开发者都能轻松上手。你可以在 AttoParser 官方文档中查看完整的语法说明。

例如,以下选择器会选中标记中任意位置所有 class="content"<div> 元素(注意:这个写法并非最简洁,后续会说明原因):

html
<div th:insert="~{mytemplate :: //div[@class='content']}">...</div>

基础语法如下:

语法含义
/x当前节点的直接子节点中,名称为 x 的元素(仅一级子节点)。
//x当前节点的所有子节点中(任意层级),名称为 x 的元素。
x[@z="v"]名称为 x 且包含属性 z、属性值为 v 的元素。
x[@z1="v1" and @z2="v2"]名称为 x,且同时包含属性 z1=v1z2=v2 的元素。
x[i]名称为 x,且在同级兄弟元素中排第 i 位的元素。
x[@z="v"][i]名称为 x、属性 z=v,且在满足该条件的同级兄弟元素中排第 i 位的元素。

不过也可使用更简洁的语法:

  1. x 完全等价于 //x:在任意层级查找名称为 x 的元素,或带有 th:ref="x"/th:fragment="x" 属性的元素(“引用”属性)。
  2. 允许省略元素名/引用名,仅通过属性筛选:例如 [@class='oneclass'] 是合法选择器,会匹配所有 class="oneclass" 的元素(不限标签名)。

高级属性选择特性:

  1. 支持多类比较运算符

    • =:等于(默认)
    • !=:不等于
    • ^=:以指定值开头
    • $=:以指定值结尾 示例:x[@class^='section'] 匹配名称为 xclass 属性值以 section 开头的元素。
  2. 属性写法兼容

    • @(XPath 风格):x[@z='v']
    • 不带 @(jQuery 风格):x[z='v'] 两种写法完全等价。
  3. 多属性条件拼接

    • XPath 风格(and 连接):x[@z1='v1' and @z2='v2']
    • jQuery 风格(链式拼接):x[@z1='v1'][@z2='v2'](也可写为 x[z1='v1'][z2='v2']) 以上写法均等价。

jQuery 风格的快捷选择器:

快捷语法等价写法含义
x.oneclassx[class='oneclass']名称为 xclass="oneclass" 的元素。
.oneclass[class='oneclass']所有 class="oneclass" 的元素(不限标签名)。
x#oneidx[id='oneid']名称为 xid="oneid" 的元素。
#oneid[id='oneid']所有 id="oneid" 的元素(不限标签名)。
x%onerefx[@th:ref='oneref' or @th:fragment='oneref']名称为 x 且带有 th:ref="oneref"/th:fragment="oneref" 的元素。
%oneref[@th:ref='oneref' or @th:fragment='oneref']所有带有 th:ref="oneref"/th:fragment="oneref" 的元素(不限标签名),等价于直接写 oneref

前文的示例:

html
<div th:insert="~{mytemplate :: //div[@class='content']}">...</div>

可简化为 jQuery 风格的简洁写法:

html
<div th:insert="~{mytemplate :: div.content}">...</div>

再看一个对比示例:

html
<div th:replace="~{mytemplate :: myfrag}">...</div>

其作用是:查找带有 th:fragment="myfrag"(或 th:ref="myfrag")的元素;若存在名为 myfrag 的标签(HTML 中不存在这类标签),也会匹配。

注意下面的不同点:

html
<div th:replace="~{mytemplate :: .myfrag}">...</div>

其作用是:仅查找所有 class="myfrag" 的元素,不关心 th:fragment/th:ref 属性。

关键补充说明

  • th:fragment/th:ref 优先级:选择器中直接写 xxx 时,优先匹配 th:fragment="xxx"/th:ref="xxx",其次匹配标签名为 xxx 的元素;
  • 层级匹配:/ 仅匹配直接子节点,// 匹配任意层级,省略层级符号时默认等价于 //
  • 运算符场景:^=/$= 常用于匹配动态属性(如 href^='https' 筛选外链、class$='-item' 匹配后缀为 -item 的类名)。

总结

  1. Thymeleaf 标记选择器兼容 XPath/CSS/jQuery 风格,核心支持层级、属性、位置三类筛选规则;
  2. 快捷写法(如 x.class/x#id/%ref)大幅简化选择器代码,是实际开发的首选;
  3. 直接写 xxx 会匹配 th:fragment/th:ref,加 .xxx 仅匹配 class,需注意两者的区别。