使用document.evaluate()如何提取<svg>元素?

7

我正在尝试使用document.evaluate()<svg>元素中提取特定的子元素。但是,我在提取<svg>本身时遇到了问题。我可以提取<svg>之前的所有内容,但无法进一步提取。例如,以下代码可以正常工作:

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

这给我带来了(缩短版):
<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>

然后我会假设这是一个简单的操作。
//*[@id="chart"]/div/div[1]/div/svg

我希望你能帮我翻译一下关于IT技术的内容。需要翻译的内容是:<svg>标签的使用问题。我尝试过所有响应类型,但都没有起作用。

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)
   );   
}    

我遇到了invalidIteratorState、空的singleNodeValue或者snapshotLength为0的情况。

示例 -> http://jsfiddle.net/hw79zp7j/

我是否存在未知的evaluate()限制,还是我的操作完全错误?

澄清一下,我的最终目标是能够在单行代码中提取例如Google可视化xAxis <text>元素。目前的情况是(请参见示例),我必须通过使用多个querySelectorAll/ getElementsByTagName等来迭代<svg>,这既不易读,也不易维护和优雅。如果能够从谷歌开发工具中获取xpath并在单行中重用它将会很好。

1个回答

6

SVG元素位于命名空间http://www.w3.org/2000/svg中,要使用XPath选择命名空间中的元素,您需要将前缀绑定到命名空间URI并在路径中使用该前缀以限定元素名称,例如svg:svg。因此,在evaluate的第三个参数中使用解析器(resolver),将您选择的前缀(例如 svg)映射到上述命名空间URI。

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)

是的,那个可行!实际上,我一直在寻找<svg>内部的命名空间(例如xmlns="xxx"或类似的),但由于没有,我就认为它不必要了。所以<svg>元素的命名空间总是隐含的吗?无论如何,接下来要做的事情是进一步获取一些内容,在进行了一些小测试之后,我意识到在层次结构中都是相同的,例如://*[@id="chart"]/div/div[1]/div/svg:svg/g:g等 - 因此,通过处理上述问题,我最终将能够使用自动化的 //*[@id="chart"]/div/div[1]/div/svg/g[3]/g[3] 代码。谢谢! - davidkonrad
1
XPath最初是为使用命名空间的XML文档定义的,在XML中,您需要编写<svg xmlns="http://www.w3.org/2000/svg">...</svg>来正确标记SVG元素并使任何用户代理识别您的SVG。但是,现在我们生活在HTML5的世界中,其中允许混合使用HTML、SVG和MathML而不声明任何命名空间。尽管如此,这些元素仍然具有命名空间,即使没有前缀选择HTML也只能按照HTML5规范中所述的方式工作,详见http://www.w3.org/TR/html5/infrastructure.html#interactions-with-xpath-and-xslt。 - Martin Honnen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接