Html 为什么 normalize-space(text()) 在按文本选择时会忽略内部节点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26819575/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why normalize-space(text()) ignores internal nodes when selecting by text?
提问by master.py
why in following example I can use //label[text()[normalize-space() = 'some label']]
or //label[normalize-space(text()) = 'some label']
to select label by text and ignore span's content? Why? I really want to understand this issue. In http://www.w3.org/TR/xpath/#function-normalize-spacethere is no info about this functionality. This is exactly what I want, but I also desperately want to know why this solution works:)
为什么在下面的示例中我可以使用//label[text()[normalize-space() = 'some label']]
或//label[normalize-space(text()) = 'some label']
按文本选择标签并忽略跨度的内容?为什么?我真的很想了解这个问题。在http://www.w3.org/TR/xpath/#function-normalize-space中没有关于此功能的信息。这正是我想要的,但我也非常想知道为什么这个解决方案有效:)
BTW, which syntax is better: //label[text()[normalize-space() = 'some label']]
vs //label[normalize-space(text()) = 'some label']
and why?
顺便说一句,哪种语法更好://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>
I'm looking for your helpful answer:)
我正在寻找您有用的答案:)
回答by Michael Kay
This has nothing to do with normalize-space(), and everything to do with text()
.
这与 normalize-space() 无关,而与text()
.
text()
is short for child::text()
, and selects the text nodes that are immediate children of the label element. Unless you are stripping whitespace text nodes, the label element in your example has two child text nodes, one of which is all whitespace, the other contains "some label" surrounded by whitespace.
text()
是 的缩写child::text()
,并选择作为标签元素的直接子元素的文本节点。除非您要剥离空白文本节点,否则示例中的 label 元素有两个子文本节点,其中一个是所有空白,另一个包含由空白包围的“某些标签”。
BTW, which syntax is better: //label[text()[normalize-space() = 'some label']] vs //label[normalize-space(text()) = 'some label'] and why?
They do different things; the one that is better is the one that does what you want to achieve.
他们做不同的事情;更好的那个是做你想要实现的目标的那个。
In XPath 1.0, the first expression selects label elements that have a child text node whose value, after whitespace normalization, equals "some label". The second selects label elements whose first child text node, after whitespace normalization, equals "some label". That's because normalize-space() (like all functions that expect a string), if you give it a node-set, takes the string value of the first node in the node-set.
在 XPath 1.0 中,第一个表达式选择具有子文本节点的标签元素,在空白规范化之后,该节点的值等于“某个标签”。第二个选择标签元素,其第一个子文本节点在空白归一化后等于“某个标签”。那是因为 normalize-space()(就像所有需要字符串的函数一样),如果你给它一个节点集,就会获取节点集中第一个节点的字符串值。
In XPath 2.0, the first expression selects label elements that have a child text node whose value, after whitespace normalization, equals "some label". The second selects label elements if they have a child text node, after whitespace normalization, equals "some label", but raises an error if the label element has more than one child text node. That's because normalize-space() (like all functions that expect a string), atomizes its argument, and reports a type error if the length of the atomized sequence is greater than one.
在 XPath 2.0 中,第一个表达式选择具有子文本节点的标签元素,在空白规范化之后,该节点的值等于“某个标签”。如果标签元素有子文本节点,则第二个选择标签元素,在空白规范化之后,等于“某个标签”,但如果标签元素具有多个子文本节点,则会引发错误。那是因为 normalize-space()(就像所有需要字符串的函数一样),将其参数原子化,如果原子化序列的长度大于 1,则会报告类型错误。
回答by BeniBela
text()
returns all text nodes that are children of the current node (the label)
text()
返回作为当前节点(标签)的子节点的所有文本节点
But some span
is not a child of the label, it is a child of the span.
但some span
不是标签的孩子,它是跨度的孩子。
You can use //text()
to get all descendant text nodes, or span/text()
to get the text nodes of the span
您可以使用//text()
获取所有后代文本节点,或span/text()
获取跨度的文本节点
--
——
You need to use //label[//text()[normalize-space() = 'some label']]
instead of //label[normalize-space(//text()) = 'some label']
, because latter only works if there is a single text node
您需要使用//label[//text()[normalize-space() = 'some label']]
而不是//label[normalize-space(//text()) = 'some label']
,因为后者仅在有单个文本节点时才有效