当前位置: 首页 > 知识库问答 >
问题:

如何在SeleniumWebDriver中使用xPath获取SVG元素?

酆翔宇
2023-03-14

我正在使用SeleniumWebDriver(Java版本)测试一个基于OpenLayers的API。

我想测试一个使用OpenLayers的功能。控制修改功能。我想单击绘制的特征(SVG),然后拖动并检查它们是否存在、可见或隐藏。

我已经画了一个多边形,并且选择了它。见下图:

这些SVG元素的HTML如下所示:

<svg id="OpenLayers_Layer_Vector_161_svgRoot" width="1235" height="495" viewBox="0 0 1235 495" style="display: block;">
    <g id="OpenLayers_Layer_Vector_161_root" transform="" style="visibility: visible;">
        <g id="OpenLayers_Layer_Vector_161_vroot">
            <path id="OpenLayers_Geometry_Polygon_200" d=" M 393.0000000000964,213.9999999999891 486.0000000003338,275.9999999997126 384.00000000036925,284.9999999994434 393.0000000000964,213.9999999999891 z" fill-rule="evenodd" fill="blue" fill-opacity="0.4" stroke="blue" stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="pointer" />
            <circle id="OpenLayers_Geometry_Point_619" cx="439.50000000021464" cy="244.99999999985084" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_621" cx="435.00000000035106" cy="280.49999999958163" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_623" cx="388.50000000023283" cy="249.4999999997126" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_202" cx="393.0000000000964" cy="213.9999999999891" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_203" cx="486.0000000003338" cy="275.9999999997126" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_204" cx="384.00000000036925" cy="284.9999999994434" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
        </g>
        <g id="OpenLayers_Layer_Vector_161_troot" />
    </g>
</svg>

假设我想选择红点。

我试过:

String xpath = "//circle[contains(@id, 'OpenLayers_Geometry_Point') AND fill = '#990000']";
List<WebElement> vertices = driver.findElements(By.xpath(xpath));

但是它总是返回一个空列表[]

我做错了什么?有人能帮我吗?

多谢了。

编辑1-功能:垂直显示可见

在单击操作之前,我想获取元素并检查它们是否可见。我正在使用这个函数。

public static boolean verticesAreVisible(WebDriver driver, String xpath) {
    List<WebElement> list = driver.findElements(By.xpath(xpath));
    if (list.isEmpty()) {
        return false;
    }
    boolean visible = true;
    for (int i = 0; i < list.size(); i++) {
        visible = visible && list.get(i).isDisplayed();
    }
    return !verticesAreNotVisible(driver) && visible;
}

编辑2-正确的xPath

// This solution from Razib is valid if the SVG is on the root node
String xpath = "/*[name()='svg']/*[name()='circle']";
// I changed it so that any descendant is valid "//"
String xpath = "//*[name()='svg']//*[name()='circle']";
// Since I wanted only the red vertices, I added this
String xpath = "//*[name()='svg']//*[name()='circle' and @fill='#990000']";

共有3个答案

辛龙野
2023-03-14

尝试@fill而不是fillOpenLayers\u Geometry\u Point而不是OpenLayers。几何学点

萧霍英
2023-03-14

要定位红色点,即具有属性fill=“#990000”且id属性包含OpenLayers\u Geometry\u Point的元素,可以使用以下任一定位器策略:

>

  • 使用xpath:

    //*[name()='svg']/*[name()='g']/*[name()='g']//*[name()='circle' and contains(@fill, '990000')][starts-with(@id, 'OpenLayers_Geometry_Point')]
    

    使用css选择器:

    svg > g > g circle[fill$='990000'][id^='OpenLayers_Geometry_Point']
    

    理想情况下,您需要诱导WebDriver等待visibilityOfAllElementsLocatedBy(),您可以使用以下定位器策略之一:

    >

    List<WebElement> vertices = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.cssSelector("svg > g > g circle[fill$='990000'][id^='OpenLayers_Geometry_Point']")));
    

    使用xpath:

    List<WebElement> vertices = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//*[name()='svg']/*[name()='g']/*[name()='g']//*[name()='circle' and contains(@fill, '990000')][starts-with(@id, 'OpenLayers_Geometry_Point')]")));
    

    您可以在以下讨论中找到一些相关的详细信息:

    • 如何通过Java使用XPath和Selenium WebDriver单击SVG元素

  • 范彭亮
    2023-03-14

    可能需要在Xpath中使用具有name属性的Actions。在您的XPath中使用它-

    "/*[name()='svg']/*[name()='SVG OBJECT']"  
    

    然后尝试以下代码段-

    WebElement svgObj = driver.findElement(By.xpath(XPATH));
    Actions actionBuilder = new Actions(driver);
    actionBuilder.click(svgObj).build().perform();
    
     类似资料:
    • 问题内容: 我有一个带有一些圆形和矩形元素的SVG对象。使用webdriver,我可以单击主要的svg对象,但不能单击其中的任何元素。问题似乎只在于单击(或任何鼠标交互),因为我可以使用getAttribute()返回其中任何下面内容的宽度,ID,x / y,文本等值。 这是HTML的示例: 还有一个WebDriver尝试右键单击矩形元素(并失败)的示例: 但这有效并返回一个值: 当WebDriv

    • 有了下面的XML示例文档,我需要发出一个XPath/XQuery表达式来获取CD元素的每个子元素的元素名。 所以我需要的查询返回标题,艺术家,国家,国家,价格,年份,任何人都可以帮助请?谢谢

    • 我正在尝试获取此代码的颜色和图像: 除了在以电流结尾的类中,这两个看起来都一样。 我的问题是我不知道如何获得元素的值。 我试过:

    • 问题陈述:我试图在网页上获取span标记的值。*该网页上有多个span标记,其中我需要4个。

    • 我正在尝试创建一个用户可以在浏览器中存储注释的应用程序。 为了弄清楚用户在文档中创建注释的位置,我正在尝试存储所选文本的xpath和偏移量。 我到处搜索过,似乎有很多从xPath字符串中检索元素的示例,但没有很好的从DOM元素中查找xPath的示例。 以下是我尝试过的: 其中getXPathForElement如下所示: 这段代码给出了一个很长的看起来很奇怪的文本,如下所示:(我认为这不是一个真正

    • 我有一个带有几个圆形和矩形元素的SVG对象。使用webdriver,我可以单击主svg对象,但不能单击其中的任何元素。问题似乎只出在点击(或任何鼠标交互)上,因为我可以使用getAttribute()返回宽度、ID、x/y、text等值,用于它下面的任何内容。 下面是HTML的一个示例: 以及WebDriver试图右键单击矩形元素(失败)的示例: 但这会起作用,并返回一个值: 当WebDriver