当我在回答关于Selenium的another question时正在尝试一些XPath SVG路径时,我发现Chrome上有一个奇怪的XPath行为(我没有尝试过其他浏览器)。
在http://www.amcharts.com/svg-maps/?map=usa上,为什么不 XPath有效?
//*[@id="chartdiv"]/div/div[1]/svg/g[7]/g/g[1]
然而这个 ?
//*[@id="chartdiv"]/div/div[1]/*[name()="svg"]/*[name()="g"][7]/*[name()="g"]/*[name()="g"][2]
我必须做出以下更改:
/g
变为/*[name()="g"]
/svg
变为/*[name()="svg"]
/path
变为/*[name()="path"]
奇怪的是,我通过右键单击HTML元素并从那里复制了XPath来获得第一个XPath。
我在http://gmsgroup.com/municenter.asp上有另一个例子,其中:
//*[@id='ext-gen203']/*[name()='svg']/*[name()='a']/*[name()='path'][starts-with(@d, 'M136.65')]/..
有效,//*[@id='ext-gen203']/*[name()='svg']/*[name()='a'][@title='Hawaii']
没有。此处,/*[name()='a'][@title='Hawaii']
无法获得<a title="Hawaii"></a>
,为什么?
答案 0 :(得分:4)
命名空间可以是前缀:
<root xmlns:ns="www.example.com"/>
或默认名称空间:
<root xmlns="www.example.com"/>
SVG位于默认命名空间中。像/svg
这样的路径表达式告诉XPath处理器查找一个名为&#34; svg&#34;的元素。而且没有任何名称空间。因此,此表达式仅匹配:
<svg/> or <svg xmlns=""/>
使用/*[name()='svg']
只能排除带前缀的命名空间。它仍然允许一个名为&#34; svg&#34;这是一个默认的命名空间,没有前缀。第二个表达式匹配
<svg xmlns="http://www.w3.org/2000/svg"/>
但不是
<ns:svg xmlns:ns="http://www.w3.org/2000/svg"/>
为了证明这一点,请考虑以下XSLT样式表:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="*[name() ='svg']">
<hit/>
</xsl:template>
</xsl:transform>
应用于以下输入,缩短的SVG文档:
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"/>
结果:
<?xml version="1.0" encoding="UTF-8"?>
<hit/>
在线查看here。
编辑(回复您的评论)
更清楚的是,这是否意味着SVG默认命名空间会覆盖页面中的命名空间,因此不会处理[@title =&#39; Hawaii&#39;]等表达式?
HTML元素本身没有命名空间 - 而SVG不会覆盖&#34;页面的命名空间。 svg
元素上的默认命名空间仅适用于自身和所有子元素(包括其中的a[@title='Hawaii']
元素。
//*[@id='ext-gen203']/*[name()='svg']/*[name()='a'][@title='Hawaii']
应该能够找到a
元素,我很惊讶它没有。
在哪里可以找到该默认命名空间的规范?
如果您的意思是默认命名空间,请查看此处:http://www.w3.org/TR/REC-xml-names/#scoping-defaulting。如果您指的是SVG规范,请研究SVG规范的以下章节:http://www.w3.org/TR/SVG/struct.html。
这是否也意味着没有比 [@ id =&#39; ext-gen203&#39;] / [name()=&更好的获取方式#39; SVG&#39;] / [名称()=&#39; A&#39;] / [名称()=&#39;路径&#39;] [开始-机智h(@d,&#39; M136.65&#39;)] / ..?
更好的方法是注册或声明这些名称空间,从而通过前缀使它们可用于Xpath表达式(正如Martin Honnen指出的那样)出)。 Chrome Dev Tools不是我的专业领域,我不能评论如何在那里做。
答案 1 :(得分:1)
HTML5和text / html允许您在一个文档中混合HTML,MathML和SVG元素,并且不要求您使用与不同词汇表关联的名称空间。但是,对于XPath,您需要确保将前缀绑定到SVG名称空间并在查询中使用该前缀,就像在DOM树中一样,SVG元素与HTML元素位于不同的名称空间中。在开发人员工具中是否可以实现这一点我不知道,但是通过API,通常可以设置命名空间解析器,将要在XPath表达式中使用的前缀映射到命名空间URL。