最常用且准确的方式是使用 not() 或 not(node()):not() 匹配不含子元素但可含文本/注释的元素,not(node()) 匹配完全无任何子节点(含空白)的元素。

要选择没有子节点的元素,XPath 中最常用且准确的方式是使用 not(*) 或 not(node()),具体取决于你对“没有子节点”的定义。
只不含元素子节点(允许文本、注释、处理指令)
用 not(*) —— 表示该元素下没有子元素(即没有其他标签),但可以有文本、空格或注释。
-
示例://div[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() = ''。










