代码之家  ›  专栏  ›  技术社区  ›  KJW

获取元素的xpath?

  •  5
  • KJW  · 技术社区  · 14 年前

    是否可以返回web元素的xpath?

    8 回复  |  直到 8 年前
        1
  •  8
  •   Community Dunja Lalic    7 年前

    不是直接来自WebDriver,但如果您真的需要:

    public String getElementXPath(WebDriver driver, WebElement element) {
        return (String)((JavascriptExecutor)driver).executeScript("gPt=function(c){if(c.id!==''){return'id(\"'+c.id+'\")'}if(c===document.body){return c.tagName}var a=0;var e=c.parentNode.childNodes;for(var b=0;b<e.length;b++){var d=e[b];if(d===c){return gPt(c.parentNode)+'/'+c.tagName+'['+(a+1)+']'}if(d.nodeType===1&&d.tagName===c.tagName){a++}}};return gPt(arguments[0]).toLowerCase();", element);
    }
    

    Javascript来自 this post ,缩小到适合一条生产线。它可能不完美,但可以让你知道去哪里。大多数驱动程序实现 JavascriptExecutor 界面,并具有在浏览器中执行Javascript的能力。 executeScript 可以返回任何原始JavaScript类型、HTML元素或上述任何类型的非嵌套列表。

    Not all browsers support xpath the same way ,因此使用这些xpath选择元素时要小心。另外,并非所有浏览器都支持本机xpath( 咳嗽 工业工程 咳嗽 ),所以这是伪造的。

        2
  •  5
  •   Ysee.mma    9 年前

    如果WebElement由by.xpath找到: 在Java上:

    public static String GetWebElementXpath(WebElement El) throws AssertionError{
            if ((El instanceof WebElement)){
                Object o = El;
                String text = o.toString();
            /* text is smth like this
            [[FirefoxDriver: firefox on WINDOWS (9170d4a5-1554-4018-adac-f3f6385370c0)] -> xpath: //div[contains(@class,'forum-topic-preview')]//div[contains(@class,'small-human')]]
            */
                text = text.substring( text.indexOf("xpath: ")+7,text.length()-1);
                return text;
            }else   {   Assert.fail("Argument is not an WebElement, his actual class is:"+El.getClass());       }
            return "";
        }
    
        3
  •  4
  •   Falkenfighter    11 年前

    以上两个答案都有相同的问题。通过返回完整的XPath .toLowerCase() 函数调用时,任何包含带大写字母的id的XPath都将不起作用。

    例子: //div[@id="deviceblock-1111"] 在标签上不起作用 <div id="deviceBlock-1111">

    但是你可以把 .toLowerCase() 取消返回,但最终XPath如下所示: //DIV[@id="deviceBlock-1111"]/DIV[2]/SELECT[1]/OPTION[5]

    要解决这个问题,请使用下面的函数。

    public String GetElementXPath(WebElement element, WebDriver driver)
    {
        return (String) ((JavascriptExecutor) driver).executeScript(
        "getXPath=function(node)" +
        "{" +
            "if (node.id !== '')" +
            "{" +
                "return '//' + node.tagName.toLowerCase() + '[@id=\"' + node.id + '\"]'" +
            "}" +
    
            "if (node === document.body)" +
            "{" +
                "return node.tagName.toLowerCase()" +
            "}" +
    
            "var nodeCount = 0;" +
            "var childNodes = node.parentNode.childNodes;" +
    
            "for (var i=0; i<childNodes.length; i++)" +
            "{" +
                "var currentNode = childNodes[i];" +
    
                "if (currentNode === node)" +
                "{" +
                    "return getXPath(node.parentNode) + 
                        '/' + node.tagName.toLowerCase() + 
                        '[' + (nodeCount+1) + ']'" +
                "}" +
    
                "if (currentNode.nodeType === 1 && " +
                    "currentNode.tagName.toLowerCase() === node.tagName.toLowerCase())" +
                "{" +
                    "nodeCount++" +
                "}" +
            "}" +
        "};" +
    
        "return getXPath(arguments[0]);", element);
    }
    

    这将从web元素返回格式正确、唯一的XPath。

    //div[@id="deviceBlock-1111"]/div[2]/select[1]/option[5]

        4
  •  1
  •   Bo Persson tox    12 年前
    public String getElementXPath(WebDriver driver, WebElement element) {
    
        String javaScript = "function getElementXPath(elt){" +
                                "var path = \"\";" +
                                "for (; elt && elt.nodeType == 1; elt = elt.parentNode){" +
                                    "idx = getElementIdx(elt);" +
                                    "xname = elt.tagName;" +
                                    "if (idx > 1){" +
                                        "xname += \"[\" + idx + \"]\";" +
                                    "}" +
                                    "path = \"/\" + xname + path;" +
                                "}" + 
                                "return path;" +
                            "}" +
                            "function getElementIdx(elt){" +
                                "var count = 1;" +
                                "for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling){" +
                                    "if(sib.nodeType == 1 && sib.tagName == elt.tagName){" +
                                        "count++;" +
                                    "}" +
                                "}" +
                                "return count;" + 
                            "}" +
                            "return getElementXPath(arguments[0]).toLowerCase();";      
    
        return (String)((JavascriptExecutor)driver).executeScript(javaScript, element);     
    
    }
    
        5
  •  1
  •   Community Dunja Lalic    7 年前

    我会直接评论 dflems ' answer ,但我没有这样做的名声。

    将整个xpath转换为小写是可以的,除非xpath包含的id值不全是小写。下面是dflems的Javascript的修改版本,但使用Python而不是Java:

    def get_xpath_from_element(driver, element):
        return driver.execute_script("gPt=function(c){if(c.id!==''){return'id(\"'+c.id+'\")'}if(c===document.body){return c.tagName}var a=0;var e=c.parentNode.childNodes;for(var b=0;b<e.length;b++){var d=e[b];if(d===c){return gPt(c.parentNode)+'/'+c.tagName.toLowerCase()+'['+(a+1)+']'}if(d.nodeType===1&&d.tagName===c.tagName){a++}}};return gPt(arguments[0]);", element)
    

        6
  •  0
  •   Sufian    10 年前

    有一种方法可以在不使用JavaScript的情况下获取元素XPath。

    1. 定义外部XPath的起点,例如body标记。
    2. 用硒检查所有可能的内部标签 NoSuchElementException .
    3. 支票 getText 用于生成的xpath列表。
        7
  •  0
  •   Ilana    9 年前
    public static String getXPathFromElement(WebElement element) {
            String elementDescription = element.toString();
            return elementDescription.substring(elementDescription.lastIndexOf("-> ") + 3, elementDescription.lastIndexOf("]"));
    }
    

    Web元素toString()如下所示:

    '[[FirefoxDriver:firefox on WINDOWS(ceb69f9f-bef4-455d-b626-ab439f195be6)]->id:pageBeanfundDescription]'

    我只是提取id/xpath。

        8
  •  0
  •   Mahbub Ansari    8 年前
    /**
     * This method return By reference for the WebElement passed to it as a parameter.
     * @param element
     * @return
     */
    public static By convertWebElementToByReference(WebElement element) 
    {
        By byLocator = null;
        String elementDescription = element.toString();
        String elementTypeAndValue[] = (elementDescription.substring(elementDescription.lastIndexOf("-> ") + 3, elementDescription.lastIndexOf("]"))).split(":");        
    
        switch (elementTypeAndValue[0].trim()) 
        {
            case "id": byLocator = By.id(elementTypeAndValue[1].trim());
               break;
    
            case "xpath": byLocator = By.xpath(elementTypeAndValue[1].trim());
               break;
    
            case "link text": byLocator = By.linkText(elementTypeAndValue[1].trim());
               break;
    
            case "tag name": byLocator = By.tagName(elementTypeAndValue[1].trim());
               break;
    
            case "class name": byLocator = By.className(elementTypeAndValue[1].trim());
               break;
    
            case "partial link text": byLocator = By.partialLinkText(elementTypeAndValue[1].trim());
               break;
    
            case "name": byLocator = By.name(elementTypeAndValue[1].trim());
               break;
    
            case "css selector": byLocator = By.cssSelector(elementTypeAndValue[1].trim());
               break;
    
            default:
                throw new RuntimeException("Invalid locator type: " + elementTypeAndValue[0].trim());
        }
    
        return byLocator;
    }