Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extract <svg> element by using document.evaluate()?

I am trying to use document.evaluate() to extract certain child elements out of a <svg> element. But I have problems by just extracting the <svg> itself. I can extract everything up to the <svg>, but no further. For example this works well :

document.evaluate('//*[@id="chart"]/div/div[1]/div', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue)

This gives me (shortened) :

<div style="position: absolute; left: 0px; top: 0px; width: 100%; height: 100%;" aria-label="Et diagram.">
    <svg width="600" height="400" aria-label="Et diagram." style="overflow: hidden;"></svg>
    <div aria-label="En repræsentation i tabelformat af dataene i diagrammet." style="position: absolute; left: -10000px; top: auto; width: 1px; height: 1px; overflow: hidden;"></div>
</div>

and then I would assume the simple

//*[@id="chart"]/div/div[1]/div/svg

would give me the <svg> - but nothing works. Have tried all respond types :

for (var type=XPathResult.ANY_TYPE; type<XPathResult.FIRST_ORDERED_NODE_TYPE+1; type ++) {
   console.dir(
      document.evaluate('//*[@id="chart"]/div/div[1]/div/svg', document, null, type, null)
   );   
}    

I get either invalidIteratorState, null singleNodeValue or a snapshotLength of 0.

demo -> http://jsfiddle.net/hw79zp7j/

Is there any limitations of evaluate() I havent heard of, or am I just doing it utterly wrong?

For clarification, my ultimate goal is to be able extract for example a google visualization xAxis <text> elements in a single line of code. As it is now (see demo) I have to iterate through the <svg> by using multiple querySelectorAll / getElementsByTagName etc, which is not very readable, maintenance friendly or elegant. It would be nice just to grab the xpath from google developer tools and reuse it in a single line.

like image 292
davidkonrad Avatar asked Jul 01 '15 13:07

davidkonrad


People also ask

What is document evaluate?

evaluate() The evaluate() method of the Document interface selects elements based on the XPath expression given in parameters. XPath expressions can be evaluated on both HTML and XML documents.

What does document evaluate return?

document. evaluate() This method evaluates XPath expressions against an XML based document (including HTML documents), and returns a XPathResult object, which can be a single node or a set of nodes. The existing documentation for this method is located at document.

What is xmlns in SVG?

It is used as the outermost element of SVG documents, but it can also be used to embed an SVG fragment inside an SVG or HTML document. Note: The xmlns attribute is only required on the outermost svg element of SVG documents. It is unnecessary for inner svg elements or inside HTML documents.


1 Answers

SVG elements are in the namespace http://www.w3.org/2000/svg and to select elements in a namespace with XPath you need to bind a prefix to the namespace URI and use that prefix in your path to qualify the element names e.g. svg:svg. So use a resolver as the third argument of evaluate that maps the prefix you can choose (e.g. svg) to the namespace URI mentioned above.

document.evaluate('//*[@id="chart"]/div/div[1]/div/svg:svg', document, 
                                function(prefix) { 
                                    if (prefix === 'svg') 
                                    { 
                                        return 'http://www.w3.org/2000/svg';
                                    }
                                    else
                                    {
                                        return null;
                                    }
                                }, type, null)
like image 67
Martin Honnen Avatar answered Oct 11 '22 13:10

Martin Honnen