4

私の Selenium アプリケーションでは、最高の要素を選択しようとしていますz-index。その値は要素自体では定義されていませんが、祖先ノードで定義されています (ネスト レベルは不明です)。さらに、display: noneそれを使用しても祖先が表示されない場合は、返されるべきではありません。

HTML の例:

  <div class="container" style="z-index: 10">
    <div style="display: none">
      <!-- this should not be selected because it is invisible (and the z-index is lower than the others) -->
      <div myattr="example"></div>
    </div>
  </div>
  <div class="container" style="z-index: 100">
    <div>
      <!-- this should not be selected because the z-index is lower than the others -->
      <div myattr="example"></div>
    </div>
  </div>
  <div class="container" style="z-index: 1000">
    <div>
      <!-- this should be selected because it is visible and has the highest z-index -->
      <div myattr="example"></div>
    </div>
  </div>

myattr="example"現在、祖先を持たないすべての要素を選択する正規表現がありますdisplay: none:

//div[@myattr='example'
and not(ancestor::div[contains(@style,'display:none')])
and not(ancestor::div[contains(@style,'display: none')])]

最高の z-index を持つ要素を選択するには、追加の条件が必要です。いわば、他の要素の上に表示されます。見つかったノードごとに、特定のクラスを持つノードが見つかるまで、すべての祖先を調べる必要があります (containerこの例では)。次に、最大の z-index 祖先を持つ要素のみを返します。

XPathでもそれは可能ですか?

4

2 に答える 2

2

私は一生懸命努力しましたが、単一の XPath 1.0 式ではこれを達成できないと思います。近づくことはできますが、そこまでではありません。

他のロジックを使用する必要があります。何千もの異なるアプローチがあります。

たとえば、すべてのcontainer要素を取得し、並べ替えて、子孫の可視性z-indexをテストします。myattr="example"

// Gets all containers - could also be Gets all elements containing z-index
List<WebElement> containers = driver.findElements(By.className("container"));

// Sorts the containers in an descending order by their z-indexes
Collections.sort(containers, Collections.reverseOrder(new Comparator<WebElement>() {
    @Override
    public int compare(WebElement o1, WebElement o2) {
        return getZindex(o1) - getZindex(o2);
    }
    private int getZindex(WebElement elem) {
        String zindex = elem.getAttribute("style").toLowerCase().replace("z-index: ", "");
        return Integer.parseInt(zindex);
    }
}));

// look for a visible candidate to return as a result
for (WebElement container : containers) {
    WebElement result = container.findElement(By.cssSelector("*[myattr='example']"));
    if (result.isDisplayed()) {
        return result;
    }
}
throw new IllegalStateException("No element found.");

編集:この回答を受け入れた後、私は質問に戻り、XPath 1.0 ソリューションを思いつきました。それは地獄のように醜く、パフォーマンスが悪く、その正確性を確認できません (あなたの例と私が試した他のいくつかの例で動作します)。そのため、上記の WebDriver アプローチを使用することをお勧めします。とにかく、私はそれを共有します:

コピーペースト可能なワンライナー:

//div[@myattr='example' and not(ancestor::div[contains(@style,'display: none')])]/ancestor::div[@class='container' and substring-after(@style,'z-index:') > substring-after(../div[not(descendant::div[contains(@style,'display: none')])]/@style,'z-index:')]

フォーマットされたバージョン:

//div
    [
        @myattr='example'
        and not(ancestor::div[contains(@style,'display: none')])
    ]
    /ancestor::div
        [
            @class='container'
            and substring-after(@style,'z-index:')
                > substring-after(
                    ../div[not(descendant::div[contains(@style,'display: none')])]/@style,
                    'z-index:')
        ]

そして、人間の言語への無料翻訳 (文字通りのものではありません!):

SELECT A VISIBLE <div @myattr='example'> NODE
//div
    [
        @myattr='example'
        and not(ancestor::div[contains(@style,'display: none')])
    ]
    THAT HAS A <div @class='container'> ANCESTOR
    /ancestor::div
        [
            @class='container'
            WHOSE z-index IS GREATER THAN z-index...
            and substring-after(@style,'z-index:')
                > substring-after(
                    ...OF ALL VISIBLE SIBLINGS
                    ../div[not(descendant::div[contains(@style,'display: none')])]/@style,
                    'z-index:')
        ]
于 2013-02-27T16:03:05.507 に答える
1

z-index の最大値を知っていると仮定しました。その場合、xpath は

"//div[contains(@style,'1000')]/div[not(contains(@style,'none'))]/div"

それ以外の場合は、以下の xpath を使用して、div のすべてのスタイル属性を取得します

List<WebElement> divTags=driver.findElements(By.xpath("//div[not(contains(@style,'none'))]/parent::div[contains(@style,'z-index')]"))
for(WebElement ele:divTags)
{
    ele.getAttribute("style");
}
  • z インデックスを変数に格納する
  • 保存された Z インデックスを解析し、数値だけを取得する
  • いくつかのロジックを使用して、それらの中で最大の数を見つけます
  • 上記のすべてのことを行うと、その要素のインデックスが保持されます。
  • 最高の z-index を見つけた後、その要素のインデックスを取得します
  • そのインデックス構造 xpath を使用します。

上記のロジックが目標の達成に役立つことを願っています。

于 2013-02-27T14:31:12.797 に答える