用Python转义XPath字面量

7 投票
1 回答
2589 浏览
提问于 2025-04-16 22:51

我正在写一个公共库,用来设置一个自动化测试套件,使用的是Selenium 2.0的Python驱动。

def verify_error_message_present(self, message):
    try:
        self.driver.find_element_by_xpath("//span[@class='error'][contains(.,'%s')]" % message)
        self.assertTrue(True, "Found an error message containing %s" % message
    except Exception, e:
        self.logger.exception(e)

我想在把消息传给XPath查询之前,对它进行转义,这样如果'message'的内容是“使用的内存插槽数量(32)超过可用的内存插槽数量(16)”时,也能正常工作。

如果不进行转义,XPath查询就会失效,因为里面有'('和')'这些符号。

在Python中,我们可以用哪个库来做到这一点呢?

我知道这个问题很简单,但我在Python方面经验不多(刚开始学)。

提前谢谢你。

补充信息

在firebug中测试时,下面的查询不会返回任何结果:

//span[@class='error'][contains(.,'The number of memory slots used (32) exceeds the number of memory slots that are available (16)')]

而下面的查询会返回想要的组件:

//span[@class='error'][contains(.,'The number of memory slots used \(32\) exceeds the number of memory slots that are available \(16\)')]

从逻辑上讲,这个问题可以通过把)替换成\)来解决,但还有其他字符也需要转义。那么有没有什么库可以更好地处理这个问题呢?

1 个回答

12

在这里,括号是可以正常使用的。它们是在一个用单引号包围的XPath字符串里面,所以不会提前结束contains条件。

问题在于,当你的字符串里面有单引号时,因为单引号会结束字符串,这样就会导致表达式出错。不幸的是,XPath字符串没有办法直接处理单引号,所以你需要用其他方法来生成这些麻烦的字符,通常是用concat('str1', "'", 'str2')这种形式。

下面是一个用Python写的函数,可以做到这一点:

def toXPathStringLiteral(s):
    if "'" not in s: return "'%s'" % s
    if '"' not in s: return '"%s"' % s
    return "concat('%s')" % s.replace("'", "',\"'\",'")

"//span[@class='error'][contains(.,%s)]" % toXPathStringLiteral(message)

撰写回答