XPath表达式中的“代码重用”

时间:2012-07-29 12:50:39

标签: .net xpath

背景:我使用的是HtmlAgilityPack(.Net),所以我不得不使用XPath 1.0,which doesn't have a lower-case implementation

我试图找到所有具有包含foo作为整个单词的属性的节点 示例:

  • “foo”匹配
  • “my foo”匹配
  • “foo bar”匹配
  • “Foo”匹配
  • “ifoo”不匹配
  • “food”不匹配

这就是我所拥有的(XPath 1.0中也没有ends-with):

//*[@*[starts-with(.,'foo ') or contains(.,' foo ') or .='foo' or substring(.,string-length(.) - 3)=' foo']]

根据this,我可以使用这种可怕的方法来降低搜索条件:

translate(.,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')

最后,我的问题:如何使用translate函数,同时保持表达式尽可能短且可读?

(额外奖励:我如何在不同的表达方式之间分享?)

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

只需使用(Tomalak答案的摘要版本):

//@*[contains(concat(' ', 
                     translate(normalize-space(), 'FOO', 'foo'), 
                     ' '), 
              ' foo '
              )
    ]

警告

永远不要在XPath表达式占位符中插入由未知代理(最终用户)接收的字符串。这为 XPath Injection attack 打开了一个巨大的漏洞。

推荐的做法是使用编译的XPath表达式并将用户提供的字符串作为参数(或XPath表达式中的 get them via a variable or function reference )传递评估已经完成。