LoginSignup
mofred13
@mofred13

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

XPathの[*]について

Q&AClosed

XPathにおける、[*]の意味について知りたいです。(div[*]やli[*]など)
*はワイルドカードだと思って使っていましたが、想定していた挙動と違うことがあって気になりました。

"/html/body/div[*]/text()" == "/html/body/div/text()"
だと思っていましたが、どうやら違うようで、

"/html/body/div[.]/text()" == "/html/body/div/text()"
の方が近いようでした。

ググった結果、[.]は[self::node()]と同じ意味だということが分かりましたが、
[*]はどういう意味になるのでしょうか。

("/html/body/*/text()" のように使うと普通にワイルドカードとして使えるのは理解しています)

0

2Answer

Comments

  1. @mofred13

    Questioner

    ご回答ありがとうございます!

    ただ、例えば下記のようなhtmlがあったときに、
    /html/body/div[*] だと1つの要素が取得できて(/html/body/div[2])、
    /html/body/div[.] だと5つの要素が取得できるのですが(/html/body/div[1]~div[5])、
    イマイチしっくりきません。
    (検証環境はChromeです)

    <html>
    
    <body>
        <div>1</div>
        <div>
            <div>2</div>
        </div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
    </body>
    
    </html>
    
    • 前にトークンがあり、そのトークンが '@', '::', '(', '[', ',', Operator のいずれでもない場合、 '*' は MultiplyOperator に、 NCName は OperatorName に解釈されなければならない。
    • ...
    • 上記以外の場合はトークンを MultiplyOperator, OperatorName, NodeType, FunctionName, AxisName のいずれにも解釈してはならない。

    ということで、前に [ がくる * が掛け算の記号として扱われることはありません。

[*][child::*] と同等です。 div[*] は何らかの子要素を持つ div 要素を取得します。


もう少し詳しく説明します。ここでの * はロケーションパス child::* の省略です。 child::* は「子要素すべて」と読み替えることができます。

たとえば /html/body/*/text()*child::* の省略です。これは「html 要素直下の body 要素直下の 子要素すべて の直下のテキストノードを取得」という意味になります。

そして、 [ ] はその中の式が真を返すかどうかをテストします。(式がロケーションパスであれば、パスに一致するノードがあれば真です。)

div[*] == div[child::*] == 「div 要素のうち式『子要素すべて』が真を返すもの」を取得、ということです。

1

Comments

  1. @mofred13

    Questioner

    ありがとうございます。
    納得しました!

Your answer might help someone💌