为什么normalize-space(text())在按文本选择时会忽略内部节点?

时间:2014-11-08 16:49:40

标签: html xpath

为什么在以下示例中我可以使用//label[text()[normalize-space() = 'some label']]//label[normalize-space(text()) = 'some label']按文字选择标签并忽略span的内容?为什么?我真的想了解这个问题。在http://www.w3.org/TR/xpath/#function-normalize-space中没有关于此功能的信息。这正是我想要的,但我也非常想知道为什么这个解决方案有效:)

BTW,哪种语法更好://label[text()[normalize-space() = 'some label']] vs //label[normalize-space(text()) = 'some label']以及为什么?

<label>
<span>some span</span>
  some label   
</label>

<label>
    other label
<span>other span</span>
</label>

我正在寻找你的回答:)

2 个答案:

答案 0 :(得分:7)

这与normalize-space()无关,而与text()无关。

text()child::text()的缩写,并选择作为label元素的直接子节点的文本节点。除非您正在剥离空白文本节点,否则示例中的label元素有两个子文本节点,其中一个是全空白,另一个包含由空格包围的“某个标签”。

BTW, which syntax is better: //label[text()[normalize-space() = 'some label']] vs //label[normalize-space(text()) = 'some label'] and why?

他们做不同的事情;更好的是做你想要达到的目标。

在XPath 1.0中,第一个表达式选择具有子文本节点的标签元素,在空白规范化之后,该节点的值等于“某个标签”。第二个选择标签元素,其第一个子文本节点在空白标准化之后等于“某个标签”。那是因为normalize-space()(就像所有期望字符串的函数一样),如果给它一个节点集,则获取节点集中第一个节点的字符串值。

在XPath 2.0中,第一个表达式选择具有子文本节点的标签元素,该子节点标准化后的值等于“某个标签”。第二个选择标签元素,如果它们具有子文本节点,在空格标准化后等于“某个标签”,但如果标签元素具有多个子文本节点则会引发错误。那是因为normalize-space()(就像所有期望字符串的函数一样),将其参数原子化,并在雾化序列的长度大于1时报告类型错误。

答案 1 :(得分:3)

text()返回当前节点(标签)

的子节点的所有文本节点

但是some span不是标签的孩子,它是跨度的孩子。

您可以使用//text()获取所有后代文本节点,或使用span/text()获取范围的文本节点

-

您需要使用//label[//text()[normalize-space() = 'some label']]代替//label[normalize-space(//text()) = 'some label'],因为后者仅在有单个文本节点时才有效