如何用XPath获取紧跟空<metamark/>的首个"."并排除子元素前置文本
解决XPath匹配后第一个"."的问题
我来帮你搞定这个XPath的匹配需求!先明确你的核心要求:只匹配**
正确的XPath表达式
metamark[not(descendant::text())]/following::text()[normalize-space()][1][starts-with(., '.')]
表达式拆解(为什么这么写)
我们一步步拆解这个表达式的逻辑,确保完全贴合你的需求:
metamark[not(descendant::text())]:先精准选中没有任何子文本的空元素 ,避免匹配带内容的metamark。/following::text():选中这个空metamark之后的所有文本节点(不管是直接兄弟文本,还是嵌套在子元素里的文本)。[normalize-space()]:过滤掉所有纯空白的文本节点,只保留有实际内容的文本。[1]:取过滤后的第一个文本节点——这就是metamark之后最靠近它的可见文本。[starts-with(., '.')]:最后检查这个文本节点是否以"."开头,符合条件才会匹配。
验证你的三种XML场景
我们把这个表达式套进你的三个案例里测试:
- 案例1:
<metamark/><anything>. <anything2>bla</anything2>.</anything>
第一个非空白文本是<anything>里的.,以"."开头 → 匹配成功。 - 案例2:
<metamark/>.<anything> <anything2>bla</anything2>.</anything>
第一个非空白文本是metamark直接后面的.,以"."开头 → 匹配成功。 - 案例3:
<metamark/><anything><anything2>bla</anything2>.</anything>
第一个非空白文本是<anything2>里的bla,不以"."开头 → 匹配失败(符合你的预期)。
为什么之前的表达式有问题?
你之前的表达式分别检查了兄弟文本和第一个兄弟元素的第一个文本,但没有考虑到兄弟元素内部可能在"."之前还有其他子元素的文本(比如案例3里的bla),导致误匹配。而这个新表达式直接找metamark之后所有文本里第一个非空白的,从根源上避免了这个问题。
内容的提问来源于stack exchange,提问作者mr. parchman
相关产品推荐
相关产品推荐

