html - 需要一个 xpath 在某个元素第一次出现之前找到特定类型的所有元素

标签 html selenium xpath

我需要一个 xpath 来获取特定元素类型的所有元素,比如输入,它出现在另一个元素第一次出现之前。问题是,目标元素和“另一个元素”之间没有适当的层次结构。并且 html 中可以存在任意数量的“另一个元素”。

我尝试使用 'following'轴,如果只有一个“另一个元素”,它就可以工作。但是如果有很多它就不起作用

<a>
    <b>
        <input>zyx</input>
        <div>abc</div>
        <span>def</span>
        <input>ghi</input>
    </b>
    <c>
        <div class="SameAttribute">Test</div>
        <input>jkl</input>
        <div>mno</div>
    </c>
    <d>
        <div class="SameAttribute">Test</div>
        <input>pqr</input>
        <div>stu</div>
    </d>
</a>

按照上面的 html 结构,我只想要 input <b> 中的元素标签。 xpath 需要忽略 input <c> 内的元素和 <d>标签 试过这个

.//*[self::input][following::div[@class = 'SameAttribute']]

但它从 <b> 中选取元素和 <c>标签。

当我尝试这个时,没有选择任何东西

.//*[self::input][following::(div[@class = 'SameAttribute'])[1]]

我无法编写包含任何标签的 xpath <b> , <c> , <d>由于其他限制

最佳答案

i want only the input elements that are within the <b> tag. the xpath needs to ignore the input elements that are within <c> and <d> tags

使用:

//b//input

I need an xpath that fetches all the elements of a particular element type, say input, that occurs before the first occurrence of another element. the problem is, there is no proper hierarchy between the targeted elements and the 'another element'. and there can be any number of 'another element' present in the html.

这不等同于上面引用的第一个要求。

您没有指定“另一个元素”的含义,但结合两个引用的要求和提供的源 xml 文档,可以逻辑地得出结论,此处的“另一个元素”表示元素 /a/b[1] 的任何后续兄弟

这些将由以下人员选择:

(//b)[1]//input

或者对于提供的 xml 文档:

/a/b[1]//input

如果文档有多个 /a/b 元素,并且您只想获取任何 input 元素之前的这些 /a/b/ 元素的 /a/{X} 后代,其中 {X} 是不同于 b 的名称,请使用:

/a/b[not(preceding-sibling::*[not(self::b)])]//input

最后,在最一般的情况下,如果您只想选择 input 元素的 b 后代,这些元素出现在 **之前* 任何其他 ( non-b ) 元素(不包括顶部元素——如果顶部元素是 b那么顶部元素的任何 input 后代都满足要求,这里是一个选择这些的 XPath 表达式:

/*//b[not(ancestor::*[not(self::b) and parent::*]) 
    and not(preceding::*[not(self::b)])]
      //input

这里我们使用的事实是,如果元素 x 在(按文档顺序)元素 y 之前,则 x 要么是 y 的祖先(属于其 ancestor::* 轴),要么是前一个元素(属于其 preceding::* 轴) )

基于 XSLT 的验证:

此转换计算所有 5 个 XPath 表达式并输出所选节点:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <xsl:copy-of select="//b//input"/>
    ==================================
    <xsl:copy-of select="(//b)[1]//input"/>
    ==================================
    <xsl:copy-of select="/a/b[1]//input"/>
    ==================================
    <xsl:copy-of select="/a/b[not(preceding-sibling::*[not(self::b)])]//input"/>
    ==================================
    <xsl:copy-of select=
    "/*//b[not(ancestor::*[not(self::b) and parent::*])
        and not(preceding::*[not(self::b)])]
          //input"/>
  </xsl:template>
</xsl:stylesheet>

应用于最初提供的 XML 文档时:

<a>
    <b>
        <input>zyx</input>
        <div>abc</div>
        <span>def</span>
        <input>ghi</input>
    </b>
    <c>
        <div class="SameAttribute">Test</div>
        <input>jkl</input>
        <div>mno</div>
    </c>
    <d>
        <div class="SameAttribute">Test</div>
        <input>pqr</input>
        <div>stu</div>
    </d>
</a>

在评估每个表达式时选择想要的、正确的结果:

<input>zyx</input>
<input>ghi</input>
    ==================================
    <input>zyx</input>
<input>ghi</input>
    ==================================
    <input>zyx</input>
<input>ghi</input>
    ==================================
    <input>zyx</input>
<input>ghi</input>
    ==================================
    <input>zyx</input>
<input>ghi</input>

关于html - 需要一个 xpath 在某个元素第一次出现之前找到特定类型的所有元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56784559/

相关文章:

node.js - 如何将上下文 Node 添加到 puppeteer 中的 xpath 查询?

python - 提取两个 P 之间的文本

jquery - 除非我指定高度,否则 Div 不会在屏幕上居中

selenium - 在 Run Keyword If - Robot Framework 中处理多个语句

XMLStarlet、XPath - 如何根据节点删除属性

java - 使用 Selenium WebDriver 确认网页中显示文本

javascript - 仅当标题悬停时,如何设置我的菜单才能滑出?

html - 在谷歌浏览器中强制/允许视频缓存

c# - 在 anchor 标记内使用 Selenium 选择图像按钮

Python、Selenium、下载所有 MIME 类型