需要一个xpath在特定元素首次出现之前查找特定类型的所有元素

时间:2019-06-27 05:38:09

标签: 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]]

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

5 个答案:

答案 0 :(得分:0)

您可以尝试使用此xpath

这是为所有输入建立索引(请为其他输入更改计数):

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

这是简单的方法,在标签input之间的<b>

//b//input

答案 1 :(得分:0)

一个似乎符合您条件的Xpath是:

//input[not(preceding-sibling::*[contains(@class,'SameAttribute')])]

这将查找所有不包含具有同级属性且包含Sameame类的同级元素的输入元素。

答案 2 :(得分:0)

按照您描述问题的方式,最简单的解决方案是//b/*。另外,如果您希望所有元素与第一个input元素具有相同的父元素,则可能需要(//input)[1]/following-sibling::*

您当然不想在这里使用following轴:仔细阅读followingfollowing-sibling之间的区别。

您的表情//*[self::input]是说//input的一种非常复杂的方式。

答案 3 :(得分:0)

我尝试使用precedingancestor轴的组合来得出解决方案。以下是对我有用的xpath
(.//div[@class='SameAttribute'])[1]/preceding::*[self::input][ancestor::a]

答案 4 :(得分:0)

  

我只需要<b>标记内的输入元素。 xpath   需要忽略<c><d>标记内的输入元素

使用

//b//input
  

我需要一个xpath来获取特定元素的所有元素   类型(例如输入),该类型先于另一个   元件。问题是,   目标元素和“另一个元素”。而且可以有任何   html中存在的“另一个元素”的数量。

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

您无需指定“另一个元素”是什么意思,而是结合两个引用的要求和提供的源xml文档,就可以从逻辑上得出结论,“另一个元素”在这里表示元素{ {1}}

这些将通过以下方式选择:

/a/b[1]

或仅针对提供的xml文档:

(//b)[1]//input

如果文档中有多个/a/b[1]//input 元素,而您只想获取所有/a/b元素之前的input个元素的/a/b/个子孙,其中{{ 1}}是不同于/a/{X}的名称,请使用:

{X}

最后,在最一般的情况下,如果只想选择在任何其他b元素之前(不包括在其中)的/a/b[not(preceding-sibling::*[not(self::b)])]//input 个元素的input个后代top元素-如果top元素是b,则top元素的任何non-b后代都满足要求,这是一个XPath表达式,用于选择这些元素:

b

在此我们使用以下事实:如果元素input在(按文档顺序)元素/*//b[not(ancestor::*[not(self::b) and parent::*]) and not(preceding::*[not(self::b)])] //input 之前,则xy的祖先(属于到其x轴)或为前一个元素(属于其y轴)

基于XSLT的验证

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

ancestor::*

应用于原始提供的XML文档

preceding::*

评估每个表达式时选择所需的正确结果

<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>