uhyohyo.net

JavaScript初級者から中級者になろう

十章第三回 属性の取得と型

このページの最終更新日:

属性を取得する

今回は、XPathにおける新しい軸が出てきます。

今まで、軸はどちらの方向にあるノードを探索するかという意味を持つものを紹介してきました。今回紹介するattribute軸は、あるノードの属性を調べることができます。最初のサンプルは次のXPath文です。

/html/attribute::lang

これは、html要素のlang属性を取得していることになります。

さて、ここで、今までXPath文の結果はノードセットでした。では、「属性を取得する」というのは何が結果になるのでしょうか。前に紹介したgetAttributeの例からいくと、属性というのは文字列で取得できそうです。

しかし、実は今回の場合、属性ノードが取得されます。

ということで、実験してみましょう。


<!doctype html>
<html lang="en">
  <head>
    <title>test</title>
  </head>
  <body>
    <p>test</p>
    <script type="text/javascript">
      var result = document.evaluate('/html/attribute::lang', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null);

      var kekka = result.singleNodeValue;
      console.log(kekka);
      console.log(kekka.nodeType === Node.ATTRIBUTE_NODE); // true
    </script>
  </body>
</html>

コンソールに表示された結果はブラウザで見るといったい何なのか分かりにくいかもしれませんが、これはnodeTypeプロパティを持ち、しかもNode.ATTRIBUTE_NODEという定数で示される種類のノードであることが分かります。これが属性ノードです。なお、属性ノードの正式名称はAttrといいます。

Attrノード

さて、このAttrから値をどう取得するのかというと、valueというプロパティがあり、それに文字列で属性の値が入っています。つまり、kekka.valueとするとlang属性の値である"en"が取得できます。

他にもできることはありますが、今回はこのAttrは本題ではないので詳しく解説しません。

XPathの型

実際のところ、Attrノードが使われることは多くありません。属性ノードなどというものが登場したことでXPathは結果としてノードセットしか返せないのかと思った人がいるかもしれませんが、もしいたとしたらそれは誤解です。XPathは文字列や数値・真偽値も扱うことができます。XPathの型は真偽値型、数値型、文字列型、そしてノードセット型の4つです。

具体的には、次のXPath文により、XPath上で属性ノードから属性の値を文字列で取り出すことができます。

string( /html/attribute::lang )

ここで、/html/attribute::langstring()で囲んでいます。これは関数のようですが、実際関数です。XPathには関数があったのです。

また、今までXPathの文法はロケーションステップを/で区切って並べるだけのものだと思っていましたが、実はそれはノードセットを取得するためのでしかなく、その結果を関数の引数にしたり、あるいは後述しますが別の式の一部に使ったりできます。

今回登場したstring関数は、引数を文字列に変換して返します。実は属性ノードは文字列に変換すると属性の値に変換されます。属性の値の取得を文字列の変換によって行っているのです。

となると、string( /html/attribute::lang )の最終的な結果は文字列型であるということになります。

では、XPathの結果の取得はどうすればよいのでしょう。実は前回紹介した結果タイプは全てノードセット用のもので、他の型の値は取得できません。そこで、新しい結果タイプを紹介します。

NUMBER_TYPE
数値である結果を取得します。プロパティnumberValueで取り出せます。
STRING_TYPE
文字列である結果を取得します。プロパティstringValueで取り出せます。
BOOLEAN_TYPE
真偽値である結果を取得します。プロパティbooleanValueで取り出せます。
ANY_TYPE
結果の型に応じて自動的に結果タイプを選びます。数値、文字列、真偽値の場合はNUMBER_TYPE,STRING_TYPE,BOOLEAN_TYPEになり、ノードセットの場合はUNORDERED_NODE_ITERATOR_TYPEとなります。

これは単純ですね。では、属性を文字列値で取得してみましょう。


<!doctype html>
<html lang="en">
  <head>
    <title>test</title>
  </head>
  <body>
    <p>test</p>
    <script type="text/javascript">
      var result = document.evaluate('string(/html/attribute::lang)', document, null, XPathResult.STRING_TYPE, null);

      var kekka = result.stringValue;
      console.log(kekka);
    </script>
  </body>
</html>

result.stringValueに直接文字列値で"en"が入っていることが分かります。

attribute軸の省略

ここでひとつ新しい省略記法を紹介しておきます。といっても単純なもので、attribute軸を@で省略できるというものです。すなわち、 /html/attribute::lang/html/@lang と書けます。これは楽ですね。