Reputation: 881
I have an html segment like this
<div id="imageholder>
<object data="1.svg" width="100%" height="100%" type="image/svg+xml">
</object>
</div>.
When i see the inspect element in Firefox/firebug i can't see the SVG file structure, but in Chrome i am able to see the svg file structure like below:
<div id="imageholder>
<object data="1.svg" width="100%" height="100%" type="image/svg+xml">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" stroke-dasharray="none"
shape-rendering="auto" font-family="'Dialog'" width="4800">
<desc>widthmm=90.48768097536195 heightmm=49.38127063754128</desc>
<g>
<g>....</g>
</g>
However, i am not able to locate svg tag or any g element through X-path. I tried with
//div[contains(@id='imageholder')]
then i get the element correctly.
//div[contains(@id='imageholder')/object]
also returns element correctly. But
//div[contains(@id='imageholder')/object/svg]
fails.
My requirement is: I need to click on several g elements of SVG image, but i am not able to reach it. Your help will be appreciated. Thanks
Some more details added on:[Dec 8,2011]
driver.findElement(By.xpath("//div[@id='imageholder']/object"));//This worked correctly
driver.findElement(By.xpath("//div[@id='imageholder']/object/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg']"));//did not work
I also tried all the possible combination XPath - Find elements by attribute namespace given on this link but could not succeed. Thanks
For more details, please find the sample code.
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9;chrome=IE8">
<body>
<div id="imageholder"><object data="1.svg" width="100%" height="100%" type="image/svg+xml"></object></div>
</body>
</html>
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.0//EN'
'http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd'>
<svg stroke-dasharray="none" shape-rendering="auto" xmlns="http://www.w3.org/2000/svg" font-family="'Dialog'"
width="4800" text-rendering="auto" fill-opacity="1" contentScriptType="text/ecmascript" color-interpolation="auto"
color-rendering="auto" preserveAspectRatio="xMidYMid meet" font-size="12" viewBox="0 0 4800 2619" fill="black"
xmlns:xlink="http://www.w3.org/1999/xlink" stroke="black" image-rendering="auto" stroke-miterlimit="10"
zoomAndPan="magnify" version="1.0" stroke-linecap="square" stroke-linejoin="miter" contentStyleType="text/css"
font-style="normal" height="2619" stroke-width="1" stroke-dashoffset="0" font-weight="normal" stroke-opacity="1"
>
<g style="fill-opacity:0.7; stroke:black; stroke-width:0.1cm;">
<circle cx="6cm" cy="2cm" r="100" style="fill:red;"
transform="translate(0,50)"/>
<circle cx="6cm" cy="2cm" r="100" style="fill:blue;"
transform="translate(70,150)"/>
<circle cx="6cm" cy="2cm" r="100" style="fill:green;"
transform="translate(-70,150)"/>
</g>
</svg>
Please click on sample.html once you save the files.
Upvotes: 4
Views: 5685
Reputation: 11
Switch to the default frame before trying to access the SVG tag, i.e frame(0). Tried many XPath solutions nothing worked, but switching to frame worked as a charm, its treating SVG as a frame here.
System.setProperty("webdriver.gecko.driver", "C:\\Users\\Administrator\\Downloads\\geckodriver-v0.18.0-win64\\geckodriver.exe");
WebDriver d = new FirefoxDriver();
d.navigate().to("file:///C:/Users/Administrator/Desktop/sample/svg.html");
Thread.sleep(2000);
d.switchTo().frame(0);
Actions builder = new Actions(d);
WebElement svgObject = d.findElement(By.xpath("(//*[name()='svg']/*[name()='g']/*[name()='circle'])[2]"));
//"style" here prints the colour of the second circle in the svg tag. ie( blue circle)
System.out.println(svgObject.getAttribute("style"));
System.out.println(svgObject.getAttribute("transform"));
System.out.println(svgObject.getAttribute("cx"));
System.out.println(svgObject.getAttribute("cy"));
System.out.println(svgObject.getAttribute("r"));
builder.moveToElement(svgObject).click();
Upvotes: 0
Reputation: 881
Got some work around to get SVG embedded document. It doesn't seems to be possible via WebElement. But through JavaScriptExecutor, we can get the complete DOM reference and through standard DOM pattern it is possible. Like: We can do->docuemnt.getElementsByTagName('OBJECT').contentDocument. This will give the complete SVG DOM reference.
The link below doesn't seem to be the direct answer of it, but possibility of Sel2.0 can be seen through this. Selenium: Can I set any of the attribute value of a WebElement in Selenium?
Might be helpful for all:-) Thanks
Upvotes: 0
Reputation: 2998
//div[contains(@id='imageholder')/object/svg
fails because you didn't tell the processor that the namespace of the svg
element is not the same as the other. See the xmlns="http://www.w3.org/2000/svg"
.
You can write : //div[contains(@id,'imageholder')]/object/*[local-name()='svg' and namespace-uri()='http://www.w3.org/2000/svg']
.
EDIT (after reading your update) :
Problem can be : in your original html file, you have a link to the svg file in your object
element.
Even if your browser incorporate the svg file in the dom, the XPath expression seems to act on the original file itself (with the href). Sorry, but I'm not aware of those kind of use cases for XPath, and can't tell you more.
Upvotes: 2