我正在尝试选择其子项没有文本内容的所有div.to_get,不包括某些元素
HTML:
<body>
<div class="to_get">
<span> </span>
<span class="exclude"> text is ignored </span>
<span> </span>
</div>
<div class="to_get">
<span> there is text here, so don't select the parent div </span>
<span class="exclude"> text is ignored </span>
<span> </span>
</div>
<div class="to_get">
<span> </span>
<span class="exclude"> text is ignored </span>
<span> there is text here, so don't select the parent div </span>
</div>
</body>
xpath尝试:
//*/body/div[@class='to_get']/descendant::text()[not(ancestor::span/@class='exclude')][normalize-space(.)='']/ancestor::div[@class='to_get']
问题是这仍然会返回第二个(和第三个)div.to_get,因为它的第3个(和第1个)跨度子节点。但是这些div应该被排除在外,因为它的第一个(和第三个)跨度孩子。
xpath应该只选择第一个div.to_get。
答案 0 :(得分:2)
以下XPath
//div[@class='to_get' and normalize-space(span[not(@class='exclude')]/text())='']
选择仅包含空div
元素的to_get
类的所有span
,不包括类span
的{{1}}元素。对于输入HTML,这仅返回第一个exclude
。
更新:注意到注释,上面的XPath只会检查第一个范围。遵循XPath
div
选择类//div[@class='to_get'][not(span[not(@class='exclude') and not(normalize-space(text())='')])]
的所有div
元素,这些元素仅包含空to_get
个元素,不包括具有类span
的元素。对于更新的输入HTML,仅返回第一个exclude
。
答案 1 :(得分:1)
您可以尝试这种方式(格式化以便于阅读):
//div[
@class='to_get'
and
not(
span[not(@class='exclude') and normalize-space()]
)
]
要与其他答案进行比较,not(normalize-space(text())='')
仅测试<span>
中的第一个文本节点是否为空,而normalize-space()
测试<span>
中的所有文本节点是否为空}} 是空的。考虑以下将传递前者而不是后者的示例:
<div class="to_get">
<span> </span>
<span class="exclude"> text is ignored </span>
<span> <br/> there is text here, so don't select the parent div </span>
</div>