如何用许多OR选项缩短长XPath表达式? [英] How to shorten long XPath expressions with many OR alternatives?
问题描述
我正努力让Selenium通过大量可选的条件XPath,寻找可能匹配的元素 - 并将它传递给对象 elmnt code>。
目前,使用 OR
运算符( | code>),代码很快变得非常重复和详尽,尤其是当有很多可能的变化时。
在下面的例子中,唯一的变化是我开始寻找 h1
, h2
或 h3
。其余部分是一样的。
pre $
在[testString1,testString2,testString3]中为单词:
try:
elmnt = driver.find_element_by_xpath(
(
// h1 [text()[contains(。,'%s')]]%word +
/ follow:p+
|+
// h1 [text()[contains(。,'%s')]]%word +
/ following:span+
|+
// h2 [text()[contains(。,'%s')]] %word +
/ follow :: p+
|+
// h2 [text()[contains(。,'%s')]]%word +
/ following :: span+
|+
// h3 [text()[contains(。,'%s')]]%word +
/ following :: p+
|+
// h3 [text()[contains(。,'%s')]]%word +
/ following:span
)
).text
除外:
传递
else:
print elmnt
break
但是在我的实际代码中,我会看到更多的变体,包括 / following ::
中的各种节点类型,除了 p
和 span
。问题:有什么方法可以简化(缩短)吗?
我的第一个希望能够做到这样的事情:
// [h1 | h2 | h3] [text( )[contains(。,'%s')]]%word
即可以将或
运算符烘焙到XPath表达式中,而不必像示例中那样使用完全详尽的字符串连接。如果是这样的话,这个想法可能会被应用于所有人。
然而,这似乎是不可能的。
解决方案是创建某种生成函数来创建整个xPath字符串,还是其他的东西?
>我会使用这个缩短的XPath(利用 self :: @ b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b-b pre $ 注意这个测试 I am working to get Selenium to go through a large number of alternative conditional XPaths, looking for elements that may match – and pass that on to the object Currently, using the In the example below, the only variation is that I start looking for But in my actual code, I will be looking at even more variations, including various node types in Question: Is there some way to simplify (shorten) this? My first hope was that it'd be possible to do something like: i.e. that the However, this does not seem to be possible. Is the solution to create some sort of generative function that creates the entire xPath string, or something else? I would use this shortened XPath (leveraging the Note that this tests that the string value of 这篇关于如何用许多OR选项缩短长XPath表达式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!// * [self :: h1或self :: h2或self :: h3] [contains(。,'%s')]%word
+ / following :: * [self :: p or self :: span]
h1
或 h2
或字符串值 > h3
包含字
变量的值(而不是直接文本节点的字符串值)。另外,如果要实际测试这些元素的字符串值是而不是包含 word
,请使用 [。='%s']
改为。elmnt
.OR
operator (|
), the code quickly gets very repetitive and exhaustive, especially when there are a lot of possible variations.h1
, h2
, or h3
. The rest is the same.for word in ["testString1", "testString2", "testString3"]:
try:
elmnt = driver.find_element_by_xpath(
(
"//h1[text()[contains(., '%s')]]" % word +
"/following::p" +
"|" +
"//h1[text()[contains(., '%s')]]" % word +
"/following::span" +
"|" +
"//h2[text()[contains(., '%s')]]" % word +
"/following::p" +
"|" +
"//h2[text()[contains(., '%s')]]" % word +
"/following::span" +
"|" +
"//h3[text()[contains(., '%s')]]" % word +
"/following::p" +
"|" +
"//h3[text()[contains(., '%s')]]" % word +
"/following::span"
)
).text
except:
pass
else:
print elmnt
break
/following::
besides p
and span
."//[h1|h2|h3][text()[contains(., '%s')]]" % word
or
operators could be "baked into" the XPath expression without having to use fully exhaustive string concatenations like in the example. And if so, that idea could've been applied across the board.self::
axis as recommended by @alecxe in a comment): "//*[self::h1 or self::h2 or self::h3][contains(., '%s')]" % word
+ "/following::*[self::p or self::span]"
h1
, or h2
, or h3
contains the value of the word
variable (rather than the string value of the immediate text nodes). Also, if you want to actually test that the string value of those elements are rather than contains word
, use [.='%s']
instead.