LoginSignup
5
2

More than 5 years have passed since last update.

XPathでいかにしてMay'nちゃんを探すのか

Posted at

最近、Webページのオートパイロットやオートパイロットでのテストで何かとお世話になっているSelenium + Junitの環境で ' (シングルクオート)を含んだ文字列を探そうとしたら思いっきり嵌ったのでメモ

Seleniumなどでエレメントを特定する際に ' (シングルクオート)が含まれている文字列を検索したい場合には ' (シングルクオート)をエスケープしなければなりませんが、残念なことにXpath 1.0の仕様では ' (シングルクオート)をエスケープする方法が用意されていませんでした。
XPath 2.0からは、例えば ' (シングルクオート)で囲われた文字列中の ' (シングルクオート)をエスケープするには ' (シングルクオート)を2個続けて書いて '' の様にエスケープするらしいのですが、Firefoxの最新版やChromeでも未だXPath 2.0は使えないらしいです。

で、結局どうしたか?というと以下の様になりました。

例えば、以下の様な文字列が含まれたエレメントをXPathで探す場合には、

<a aria-label="アプリ May'n ちゃん &quot;Love&quot; <1>" href="#MarketListingPlace:p=tmp.03831173739257532153.1317485953465" data-column="TITLE"><img src="gwt/placeholder_icon_24.png" role="presentation"><div> <div>May'n ちゃん "Love" &lt;1&gt;</div> <div></div> </div> </a>

以下の様にします (Firefox quantamのconsoleで検索する場合)

$x("//a[@aria-label=concat('アプリ May', \"'\", 'n ちゃん \"Love\" <1>')]")

Selenium + Junitなら以下の様な感じで

Selenium + JunitのBy.xpathで検索

  searchString = "アプリ May'n ちゃん \"Love\" <1>";
  xPathStringLiteral = toXPathStringLiteral(searchString);
  searchXpath = "//a[@aria-label=" + xPathStringLiteral + "]";
  wait.until(ExpectedConditions.elementToBeClickable(By.xpath(searchXpath))

toXPathStringLiteral

  private String toXPathStringLiteral(String string) {
    if ( string.indexOf("'") == -1 ) {
        return "'" + string + "'";
    }
    if ( string.indexOf('"') == -1 ) {
        return '"' + string + '"';
    }
    return ("concat('" + string.replace("'", "', \"'\", '") + "')");
  }

…と恐ろしく面倒でした

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2