找不到Chrome DevTools提供的XPath

Sté*_*ert 3 html selenium xpath svg google-chrome

当我在回答有关Selenium的另一个问题时尝试一些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>,为什么?

Mat*_*ler 5

命名空间可以添加前缀:

<root xmlns:ns="www.example.com"/>
Run Code Online (Sandbox Code Playgroud)

或默认名称空间:

<root xmlns="www.example.com"/>
Run Code Online (Sandbox Code Playgroud)

SVG在默认名称空间中。路径表达式类似,它/svg告诉XPath处理器寻找一个称为“ svg”且没有任何名称空间的元素。因此,此表达式仅匹配:

<svg/>   or <svg xmlns=""/>
Run Code Online (Sandbox Code Playgroud)

使用/*[name()='svg']仅排除前缀的名称空间。它仍然允许一个名为“ svg”的元素,并且该元素位于默认名称空间中,没有前缀。第二个表达式匹配

<svg xmlns="http://www.w3.org/2000/svg"/>
Run Code Online (Sandbox Code Playgroud)

但不是

<ns:svg xmlns:ns="http://www.w3.org/2000/svg"/>
Run Code Online (Sandbox Code Playgroud)

为了证明这一点,请考虑以下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>
Run Code Online (Sandbox Code Playgroud)

缩短的SVG文档应用于以下输入:

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg"/>
Run Code Online (Sandbox Code Playgroud)

结果是:

<?xml version="1.0" encoding="UTF-8"?>
<hit/>
Run Code Online (Sandbox Code Playgroud)

在此在线查看


编辑(回复您的评论)

更清楚地说,这是否意味着SVG默认名称空间会覆盖页面中的默认名称空间,因此不处理诸如[@ title ='Hawaii']之类的表达式?

HTML元素本身没有名称空间-SVG不会“覆盖”页面的名称空间。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 ='ext-gen203'] / [name()='svg'] / [name()='a'] / [name ]更好的获取方法了()='path'] [starts-wit ?? h(@d,'M136.65')] / ..?

更好的方法是注册声明这些名称空间,从而通过前缀使它们可用于Xpath表达式(如Martin Honnen所指出的)。Chrome开发工具不是我的专业领域,因此我无法在其中发表评论。