Yos*_*ale 42 xpath if-statement
似乎xpath中所有丰富的函数都可以执行"if".但是,我的引擎一直坚持"没有这样的功能",我几乎没有在网上找到任何文档(我发现了一些可疑的来源,但他们的语法不起作用)
我需要从字符串的末尾删除':'(如果存在),所以我想这样做:
if (fn:ends-with(//div [@id='head']/text(),': '))
then (fn:substring-before(//div [@id='head']/text(),': ') )
else (//div [@id='head']/text())
Run Code Online (Sandbox Code Playgroud)
有什么建议?
Tom*_*lak 62
是的,有一种方法可以在XPath 1.0中实现:
concat( substring($s1, 1, number($condition) * string-length($s1)), substring($s2, 1, number(not($condition)) * string-length($s2)) )
这取决于两个互斥字符串的串联,如果条件为false(0 * string-length(...)),则第一个为空,如果条件为真,则第二个为空.这被称为"Becker的方法",归功于Oliver Becker.
在你的情况下:
concat(
substring(
substring-before(//div[@id='head']/text(), ': '),
1,
number(
ends-with(//div[@id='head']/text(), ': ')
)
* string-length(substring-before(//div [@id='head']/text(), ': '))
),
substring(
//div[@id='head']/text(),
1,
number(not(
ends-with(//div[@id='head']/text(), ': ')
))
* string-length(//div[@id='head']/text())
)
)
虽然我会试图摆脱"//"以前的一切.
此外,有可能//div[@id='head']返回多个节点.
请注意这一点 - 使用//div[@id='head'][1]更具防御性.
Nol*_*rin 23
W3.org上XPath 2.0的官方语言规范详细说明了该语言确实支持if语句.特别参见第3.8节"条件表达式".除了语法格式和解释,它还给出了以下示例:
if ($widget1/unit-cost < $widget2/unit-cost)
then $widget1
else $widget2
Run Code Online (Sandbox Code Playgroud)
这表明你不应该在表达式周围加上括号(否则语法看起来是正确的).我并不完全自信,但肯定值得一试.因此,您需要将查询更改为如下所示:
if (fn:ends-with(//div [@id='head']/text(),': '))
then fn:substring-before(//div [@id='head']/text(),': ')
else //div [@id='head']/text()
Run Code Online (Sandbox Code Playgroud)
我强烈怀疑这可能会解决它,因为你的XPath引擎似乎试图将其解释if为一个函数,它实际上是一种特殊的语言结构.
最后,指出显而易见的,确保您的XPath引擎确实支持XPath 2.0(而不是早期版本)!我不相信条件表达式是以前版本的XPath的一部分.