是否存在类似于System.IO.Path.Combine()的XPath串联操作?

时间:2014-10-07 20:16:37

标签: .net xml xpath

System.IO.Path.Combine允许将C:\Users\PeterDesktop\photo.jpg等路径合并到C:\Users\Peter\Desktop\photo.jpg中。在串联期间智能处理路径分隔符是其主要优点之一:无论{1}在第一条路径的末尾是否存在,连接始终都能正常工作。

是否有一些类似的机制可用于Xpath?

预期行为:
\ + /Customer/Order => LineItem/Description/text()

1 个答案:

答案 0 :(得分:2)

您使用了.net标记,因此我推导您使用XPath 1.0。

使用concat($string1, $string2, ..., $stringN) XPath 1.0 中连接固定数量的原子字符串很简单,例如

concat('/Customer/Order', '/', 'LineItem/Description/text()')

然而,这需要知道是否存在拖尾斜线。 XPath 1.0并不真正了解案例区别,并且具有非常有限的字符串操作功能,您会遇到相当丑陋的谓词黑客和重复的字符串。

concat('/Customer/Order',
       '/'['/' != substring('/Customer/Order', string-length('/Customer/Order'))],
       'LineItem/Description/text()'
)

使用 XPath 2.0 使用新引入的ends-with(...)函数和if-then-else子句,您可以执行类似

的操作
concat('/Customer/Order',
       if (ends-with('/Customer/Order', '/'))
       then ''
       else '/',
       'LineItem/Description/text()'
)

或稍微短暂

concat('/Customer/Order',
       '/'[not(ends-with('/Customer/Order', '/'))],
       'LineItem/Description/text()'
)

最后使用带有单项循环的hack来消除重复变量的要求:

for $string in '/Customer/Order'
return 
  concat($string,
         '/'[not(ends-with($string, '/'))],
         'LineItem/Description/text()'
  )

结论:不要考虑"复杂" XPath中的字符串操作,尤其不是XPath 1.0。使用XPath 2.0看起来好多了,使用XQuery很有趣。