最常用且准确的方式是使用 not() 或 not(node()):not() 匹配不含子元素但可含文本/注释的元素,not(node()) 匹配完全无任何子节点(含空白)的元素。
要选择没有子节点的元素,XPath 中最常用且准确的方式是使用 not(*) 或 not(node()),具体取决于你对“没有子节点”的定义。
用 not(*) —— 表示该元素下没有子元素(即没有其他标签),但可以有文本、

- 常见场景:匹配纯文本容器、空 div、带文字但无嵌套标签的元素
完全不含任何子节点(包括文本、注释等)
用 not(node()) —— 表示该元素下连文本、换行、空格、注释都没有,是真正“空”的元素。
-
示例://span[not(node())] → 匹配完全空白的
或 (注意:含空白字符也算 node(),所以严格来说,not(node()) 要求内部完全无内容,连空白也不行)
- 更稳妥写法(忽略空白文本):
//span[not(*) and normalize-space() = ''],兼顾常见 HTML 中的换行缩进
补充说明:为什么不用 * = '' 或 string-length() = 0?
这些写法容易误判:
-
*/text() = '' 语法错误,不能直接比较
-
string-length(.) = 0 会把所有子元素的文本拼起来再算长度,如果子元素里有文本,即使父元素没直接文本也会被漏掉
-
normalize-space() = '' 单独用不保险,因为它不区分是否含子元素;必须和 not(*) 组合才准确
基本上就这些。核心记两点:要排除子标签就用 not(*),要连空白都不要就用 not(node()) 或组合 not(*) and normalize-space() = ''。