【问题标题】:Selenium / getElements By XPATH and CONTAINS (JAVA)Selenium / getElements 通过 XPATH 和 CONTAINS (JAVA)
【发布时间】:2016-09-02 10:07:33
【问题描述】:

我有一个动态链接列表,其中还包含动态IDsCSS 以及获取元素列表的所有其他选项,但只有一种方式没有用处。使用contains()。但以哪种方式?

该列表包含XPATH 值,如下所示:

//a[@id='contentDataTable:4711:startMenu']/span
//a[@id='contentDataTable:4712:startMenu']/span
//a[@id='contentDataTable:4713:startMenu']/span
..
//a[@id='contentDataTable:4714:startMenu']/span

我不能使用匹配,因为 XPATH 1.0 仅支持 Selenium。所以我正在寻找正确的contains() 呼叫...

第一个想法是

xpath=//a[contains(@id, 'contentDataTable:')]

但它不起作用。

我是如何尝试获取元素的:

public List<WebElement> getWebElements(Boolean isDebug, Boolean isHPOMDebug, RemoteWebDriver remWebDriver, String htmlType, String htmlValue, String actField) {
    List<WebElement> webElements = null;
    String           webRequest  = "";

    try {
        switch (htmlType) {
            case "XPATH":
                webRequest  = htmlValue;
                webElements = remWebDriver.findElements(By.xpath(webRequest));
                break;

            case "LINKTEXT":
                webRequest  = htmlValue;
                webElements = remWebDriver.findElements(By.linkText(webRequest));
                break;

            case "LINKTEXTPART":
                webRequest  = htmlValue;
                webElements = remWebDriver.findElements(By.partialLinkText(webRequest));
                break;

            case "CSS":
                webRequest  = htmlValue;
                webElements = remWebDriver.findElements(By.cssSelector(webRequest));
                break;

            case "TAG":
                webRequest  = htmlValue;
                webElements = remWebDriver.findElements(By.tagName(webRequest));
                break;

            case "ID":
                webRequest  = actField;
                webElements = remWebDriver.findElements(By.id(webRequest));
                break;

            case "NAME":
                webRequest  = actField;
                webElements = remWebDriver.findElements(By.name(webRequest));
            break;


            default:
                webElements = null;
        } // END OF INNER SWTICH

        if (isDebug && webElements != null && webElements.size() > 1) {
            logger.log(LogStatus.INFO, "getWebElements: " + webRequest + " FOUND: " + webElements.size());
            for (int i=0;i<webElements.size(); i++) {
                logger.log(LogStatus.INFO, "getWebElements: (" + i + ") TEXT = [" + webElements.get(i).getText()     + "]");
                logger.log(LogStatus.INFO, "getWebElements: (" + i + ") TAG  = [" + webElements.get(i).getTagName()  + "]");
                logger.log(LogStatus.INFO, "getWebElements: (" + i + ") LOC  = [" + webElements.get(i).getLocation() + "]");
            }
            report.flush();
        }

    }
    catch (Exception e) {
        e.printStackTrace();
        webElements = null;
    }

    return(webElements);
}

【问题讨论】:

  • 为什么你认为它不起作用?它或//a[starts-with(@id, 'contentDataTable:')] 应该可以工作。
  • 您提供的 xpath 看起来不错,所以为什么这个 xPath 不起作用?有什么例外吗??
  • 您的 xpath 看起来不错,是否已直接在 firefox 或 chome 中使用您的 xpath 对其进行了测试?
  • @splash58 我得到一个空指针异常...我再检查一次,也许我是个白痴:)
  • //a[@id='contentDataTable:4713:startMenu']/span 是否返回结果?

标签: java selenium xpath contains elements


【解决方案1】:

实际上,您的xpath 是正确的,并且您用于获取元素的方法getWebElements(Boolean isDebug, Boolean isHPOMDebug, RemoteWebDriver remWebDriver, String htmlType, String htmlValue, String actField) 的Java 代码看起来也不错。

您注释掉的行:-

我遇到了一个空指针异常...我再次检查一下,也许我是个白痴

你得到NullPointerException,因为你首先将webElements变量初始化为null,这是错误的。

你应该改变这一行:-

List<WebElement> webElements = null;

List<WebElement> webElements = new ArrayList<WebElement>();

【讨论】:

  • 我认为你错了。空指针仅通过使用包含发生(!!!)。该方法始终与您在上面看到的相同。
  • @OldMan 不,仅供参考 findElements 永远不会返回 null,它返回 WebElement 列表或空列表,所以很可能这是空指针的原因,您需要将该行更改为建议..
  • 因为null = list 没有意义,所以它总是会抛出NullPointerException
  • 嗯,它也会产生异常,并且如果我有异常,我将返回值设置为null;我想这就是稍后空指针异常的重点......我目前正在检查这个......;)也许我在这个细节上是个白痴......
  • 是的,这就是空指针异常的要点……如果返回值为“空”,它会在稍后发生。
【解决方案2】:

如果它没有获得您需要的元素,那么页面上可能还有一些其他元素适合 xpath。你可以像这样改进你的 xpath;

webDriver.findElements(By.xpath("//a[contains(@id, 'contentDataTable') and contains(@id, 'startMenu')]"))

【讨论】:

  • 也谢谢你。它有助于找到正确的包含逻辑。
【解决方案3】:

很容易为此获得一个 css 选择器。 如果您使用以下选择器之一,CSS 应该可以正常工作:

a[id*=contentDataTable][id*=startMenu]
a[id*=contentDataTable]

这个选择器的作用是: - 查找 id 包含 contentDataTable 的 &lt;a&gt; 元素 - 对于同一个元素,我们可以添加另一个条件,即 id 也应该包含 startMenu

如果我们使用空格,例如:div a[id*=contentDataTable] 将意味着找到一个元素 &lt;a&gt;,其 id 包含 contentDataTable,但该元素应该在 div 内。

您可以做的另一件事是从您的 xpath 中删除“:”,看看这是否是错误的问题。

在 w3schools 上对 Css 选择器进行了很好的解释,您会看到一个包含一些基本选择器的表格,您应该阅读它们以更好地理解。

请查看w3schools css selectors

【讨论】:

  • 不,您可以使用 css 识别几乎任何元素,如果您查看我提供的链接,您会发现您可以使用 id、class、tags 和任何其他属性选择大多数元素。
  • 第一个选项没有找到,最后一个太多了——但这似乎是一种方式......
  • 您需要缩小查找链接的部分或添加更多限制。例如 a[id*=contentDataTable].myClass 意味着元素 a 也应该有类 myClass
  • 这是真正的问题。所有元素的唯一区别是... //a[@id='contentDataTable:4711:startMenu']/span //a[@id='contentDataTable:4712:startMenu']/span ...之间的值在里面 :。所有其他部分都是相同的。
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 2011-08-04
  • 1970-01-01
  • 2019-07-30
  • 2017-06-09
相关资源
最近更新 更多