META情報の取得について


0   名前: BLUE : 2006/05/31(水) 18:01  ID:niJ0Eyo9

HTMLファイルに記述してあるMETA情報を
Javascriptで取得することは可能でしょうか?

可能であれば、その方法を教えていただきたいと思います。

よろしくお願いします。

1   名前: Pid ◆byEkK9OALr : 2006/05/31(水) 18:01
Traditional DHTML:
var source = document.documentElement.innerHTML;
var result = source.match (/<meta[^>]+>/g);

for (var i = 0, I = result.length; i < I; i++) {
    alert ( result[i] );
}


DOM Core:
var nodes = document.getElementsByTagName ('meta');
// var nodes = document.getElementsByTagNameNS ('http://www.w3.org/1999/xhtml', 'meta');

for (var i = 0, I = nodes.length; i < I; i++) {
    alert ( nodes[i].content );
}


DOM HTML (not XHTML):
var nodes = document.getElementsByName ('description');
var nodes = document.getElementsByName ('keywords');


DOM Traversal:
var root = document.documentElement;
var whatToShow = NodeFilter.SHOW_ELEMENT;
var filter = function (node) {
    if ('META' == node.tagName || 'meta' == node.localName)
        return NodeFilter.FILTER_ACCEPT;
    else
        return NodeFilter.FILTER_SKIP;
};
var entityReferenceExpansion = false;
var iterator = document.createNodeIterator (root, whatToShow, filter, entityReferenceExpansion);

while (iterator.nextNode ()) {
    alert ( result.currentNode.content );
}


DOM XPath:
var expression = '/html/head/meta';
// var expression = '//*[namespace-uri()="http://www.w3.org/1999/xhtml" and name()="meta"]';
var contextNode = document.documentElement;
var resolver = document.createNSResolver (document.documentElement);
var type = XPathResult.ORDERED_NODE_SNAPSHOT_TYPE;
var result = document.evaluate (expression, contextNode, resolver, type, null);

for (var i = 0, I = result.snapshotLength; i < I; i++) {
    alert ( result.snapshotItem (i).content );
}


2   名前: Pid ◆byEkK9OALr : 2006/05/31(水) 18:01
>>1 XPath 訂正。
name()="meta" → local-name()="meta"

MSIE's DHTML:
var nodes = document.all.tags ('meta');


MSIE's XPath:
document.setProperty ('SelectionLanguage', 'XPath');
var expression = '/html/head/meta';
// var expression = '//*[namespace-uri()="http://www.w3.org/1999/xhtml" and local-name()="meta"]';
var contextNode = document.documentElement;
var result = contextNode.selectNodes (expression);


まだあるかな……。

3   名前: BLUE : 2006/05/31(水) 18:01  ID:niJ0Eyo9
ありがとうございます。
早速試してみたのですが、思うように出力できません。

教えていただいた
Traditional DHTML:
を使用したのですが、

実行すると、
<meta[^>
と出力されます。

source.match (/<meta[^>]+>/g)
の部分を色々変更してみたのですが、エラーになってしまいます。

恐れ入りますが、再度教えていただけますか?

4   名前: Pid ◆byEkK9OALr : 2006/05/31(水) 18:01
どんなブラウザで,どのように実行なさったのでしょうか(一応,こちらでは動作確認済です)。

あと,>>1-2 のように書いておいて何ですが,DOM Core を使うのが無難です。



文字列操作でタグ処理を行うのは危険ですし,何より面倒ですから,パース済みの DOM オブジェクトを扱う方が楽だと思います。なお,DOM Traversal は Gecko,Safari,Opera で(ただし NodeIterator ではなく TreeWalker),DOM XPath は Gecko,Opera9 で使用できます。これらは取得するノードの条件を細かく指定できるので,用途によっては(特に,今回のようなメタ情報を扱うときには)大変便利です。

5   名前: BLUE : 2006/05/31(水) 18:01  ID:niJ0Eyo9
推奨いただいた通り、Dom Coreを使用することにしました。
こちらの環境でも問題なく動作することが確認できました。
ありがとうございます!!

これを使用する際、METAのタグが数個存在している場合に
nameで指定したものだけを抽出することは可能なのでしょうか?

度々恐れ入りますが、よろしくお願いします。

6   名前: Pid ◆byEkK9OALr : 2006/05/31(水) 18:01
> METAのタグが数個存在している場合にnameで指定したものだけを抽出することは可能なのでしょうか?

たぶんそういう流れになるでしょうから,>>1-2 にいろいろ書いたんですよね (^^;)。

DOM Core(+ HTML)では,name 属性値からノードを逆引きすることはできません。いったん meta 要素ノードを全部取得してから,ループで回して各要素の属性を調べる必要があります。

var nodes = document.getElementsByTagName ('meta');

for (var i = 0, I = nodes.length; i < I; i++) {
    if ('description' == nodes[i].name)
        alert ( nodes[i].content );
}


DOM HTML ならば,指定した name 属性値を持つ要素の集合を取得できます。ところが,今度はそれが meta 要素であるかどうかをループで回して調べる必要があります。

// このメソッドは大文字・小文字を区別することに注意
var nodes = document.getElementsByName ('description');

for (var i = 0, I = nodes.length; i < I; i++) {
    if ('META' == nodes[i].tagName)
        alert ( nodes[i].content );
}


さらに,この方法は HTML 文書を扱う場合に限られる,ということに注意して下さい。XHTML 文書の場合,getElementsByName が返すのはフォーム部品のみと決められていますので,そもそも meta 要素の取得ができません。



* * *

もし実行環境を限定して良いのなら,DOM Traversal と DOM XPath は強力です。

DOM Traversal の場合,対象ノードの条件をフィルタ関数で定義できます。

var iterator = document.createTreeWalker (
    document.documentElement,
    NodeFilter.SHOW_ELEMENT,
    function (node) {
        if (('META' == node.tagName || 'meta' == node.localName) && ('description' == node.name))
            return NodeFilter.FILTER_ACCEPT;
        else
            return NodeFilter.FILTER_SKIP;
    },
    false
);

// meta[@name="description"] 要素のみ対象
while (iterator.nextNode ()) {
    alert ( result.currentNode.content );
}


DOM XPath の場合,当然ながら XPath の述語が使えます(MSIE XPath も同様)。

var result = document.evaluate (
    '/html/head/meta[@name="description"]',
    // '//*[namespace-uri()="http://www.w3.org/1999/xhtml" and local-name()="meta" and @name="description"]',
    document.documentElement,
    document.createNSResolver (document.documentElement),
    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
    null
);

// meta[@name="description"] 要素のみ対象
for (var i = 0, I = result.snapshotLength; i < I; i++) {
    alert ( result.snapshotItem (i).content );
}


7   名前: BLUE : 2006/05/31(水) 18:01  ID:niJ0Eyo9
> たぶんそういう流れになるでしょうから,>>1-2 にいろいろ書いたんですよね (^^;)。

申し訳ないです・・。
ありがとうございます!

早速確認してみます!!

一覧へ戻る