仅包含名为 X 的子元素的元素的 XPath?

问题描述 投票:0回答:2

假设我有这个例子:

<div>
<p>some text <em>emphasized text</em> some other text</p>
<p><em>The paragraph I want to capture</em></p>
<p>some text <em>emphasized text</em> some other text and <em>other em text</em> until the end.</p>
</div>

我要选择的是第二段(但也可能是第三段或第一段)。问题是这里

p
em
是相邻的。
<p>
<em>
之间没有任何文字,开头和结尾都没有。所有文字都在里面
<em>xyz</em>

如何通过 XPath 查询获取它?

我尝试了

//p/em
,/
/p/child:em
//em/parent:p
,所有这些都选择了三个段落,因为所有
em
都是
p
的子级。
//p[starts-with(.,'./em')]
也没有帮助。

html xml xpath
2个回答
1
投票

这是另一个 Xpath,它将选择只有

em
而没有直接文本的段落。

//p[not(text())][em]


1
投票

更新

根据评论,OP 澄清:

是的,我想捕获仅包含强调文本的任何段落,它是否包含在一个或多个

em
标签中。

因此,这次更新了 XPath,

//p[em][not(node()[not(self::em)])]

将选择带有一个或多个

p
子元素的所有
em
元素,但不选择任何类型的其他子元素 — 仅选择完全强调的段落。


旧答案

这个 XPath,

//p[count(node())=1][em]

将选择具有单个子节点(即

p
元素)的所有
em
元素。


说明

  • //p
    选择文档中的所有
    p
    元素。
  • [count(node())=1]
    仅过滤那些具有单个子
    p
    node()
    元素。由于
    node()
    匹配 any 类型的节点(包括元素节点和文本节点),因此它将确保仅选择具有任何类型的单个子代的
    p
    元素。
  • [em]
    仅过滤那些具有
    p
    子元素的单子
    em
    元素。

因此,对于您输入的XML/HTML,只有目标

p

<p><em>The paragraph I want to capture</em></p>

将被选中。如果还有另一个

p
带着三个
em
孩子,

<p><em>Do</em><em>not</em><em>select</em></p>

或一个

em
子元素和其他元素子元素,

<p><em>Do</em><sup>not</sup><sub>select!</sub><span> or else!</span></p>

此类

p
元素将不会被选择。

警告:当前接受的答案中的XPath,

//p[not(text())][em]
,然而,会选择这样的
p
元素,这在我看来并不是您的意图。


© www.soinside.com 2019 - 2024. All rights reserved.