スキップしてメイン コンテンツに移動

些細な日常

JavaScriptのFetchで取得したデータをDocumentへ適合できるDOMParserの使い方

JavaScriptのプログラミングでサーバーを介したデータの受け渡し:Ajax通信を行う仕組みの一つにFetch APIがある。オブジェクトに最初からウェブの送受信の時間差の難点を克服するPromiseを想定して使えるのが特徴で、旧来のXMLHttpRequest APIと比べて便利に刷新された機能を有する。

しかし取得するデータがDocumentインターフェースに属さないのがちょっと使い辛い。

例えばfetch()メソッドでhtmlファイルのデータをtextで受け取ってもそこからHTMLを操作するのはUSVStringだから合わなくて全く不可能なのが厄介みたいな場合が出て来る。

Fetch APIはデータに特化して読み書きに純粋に注力するべく考案されているのか、少なくともhtmlファイルなどを一つのDOMツリーとして種々と操作するには却って旧来のXMLHttpRequestこそまだ便利だし、十分に使える状況なんだけれどもその他は不便なので、Fetch APIでも何とかならないかと望んでしまう。

DOMParserを使うとFetchのデータでもDocumentへ適合できる

幸いにも無理ではない。Fetchのデータにかぎらず、Documentへパース/解析して変換できる方法がJavaScriptにはあってDOMParserという。

使い方はとても簡単で、new演算子でコンストラクタ関数のオブジェクトを作成したらさらに引数にデータを入れたparseFromString()メソッドをかけてデータを受け取り直す。

DOMParserの使い方の見本のソースコード

var pso = new DOMParser();
var psd = pso.parseFromString(データ, "MINE type");

DOMParserのパースは三種類のファイルに対応している。

パースされるファイルとMINE typeの組み合わせ

xmlファイル/XMLDocument
application/xml
text/xml
svgファイル/SVGDocument
image/svg+xml
htmlファイル/HTMLDocument
text/html

xmlファイルの二つのMINE typeはRFCの技術仕様で、2014年から「どちらでもよい、が、application/xmlを推奨」(xmlのContent-Typeはapplication/xmlか、それともtext/xml?)と定められている。

Fetchで取得したデータをDOMParserで変換する方法

送受信されるBodyに特有のデータが幾つかあるけど、しかしHTMLなどのDocumentの記述/マークアップをそのままの仕方で持っているのはtextだけで、DOMParserで変換すれば直ぐにDOMツリーとして扱えるようになる。

htmlファイルのtextをHTMLDocumentへパースするサンプル

JavaScript

var url1 ="/";
fetch (url1).then ((response1) => response1.text()).then ((text) => {
var pso1 = new DOMParser();
var psd1 = pso1.parseFromString(text, "text/html");
var txh1 = psd1.querySelector("h1#blog-title").textContent;
var bt1 = document.createElement("p");
var lk1 = document.createElement("a");
lk1.setAttribute("href", url1);
lk1.textContent = txh1;
r1.appendChild(bt1.appendChild(lk1));
lk1.insertAdjacentHTML("afterend", "(トップページ)");
});

※変数の「r1」は実行結果を表示するための親要素のIDだ。

実行結果

トップページ(ルートドメインの「/」のURL)のhtmlファイルからブログ名(h1#blog-titleの文章)を取得してリンク(aタグ)と添え書きを付けて段落(pタグ)に表示している。

Fetchのtext()メソッドで取得したtextデータのhtmlファイルなどをセレクターで分けたりして操作したい場合には事前にDOMParserでパースして相応のDocumentへ変換しながら元のファイルのDOMツリーの状態に戻さないとプログラミングを受け付けない。

htmlファイルのReadableStreamをHTMLDocumentへパースするサンプル

もう一つReadableStreamでもDocumentを使うかも知れない。Fetch APIをStreams APIと組み合わせるとデータの読み込みと書き出しを漸次的に操作することができる。このとき、必要なデータの種別がReadableStreamになって他のデータでは動作しないんだ。

ReadableStreamはByteという数字の羅列だから通常の場合でも最終的にデコード/解読して使われるけれどもhtmlファイルなどはさらにパースするとDocumentとしても扱えるようになる。

JavaScript

var url2 ="/";
const dcd = new TextDecoder();
var btc = "";
fetch (url2).then ((response2) => response2.body.getReader()).then ((reader) => {
function chunk({done, value}) {
if (done) {
return;
}
btc += dcd.decode(value);
if (/<\/h1>/.test(btc)) {
var pso2 = new DOMParser();
var psd2 = pso2.parseFromString(btc, "text/html");
var txh2 = psd2.querySelector("h1#blog-title").textContent;
var bt2 = document.createElement("p");
var lk2 = document.createElement("a");
lk2.setAttribute("href", url2);
lk2.textContent = txh2;
r2.appendChild(bt2.appendChild(lk2));
lk2.insertAdjacentHTML("afterend", "(トップページ)");
return;
}
reader.read().then(chunk);
}
reader.read().then(chunk);
});

※変数の「r2」は実行結果を表示するための親要素のIDだ。

実行結果

トップページ(ルートドメインの「/」のURL)のhtmlファイルからブログ名(h1#blog-titleの文章)を取得してリンク(aタグ)と添え書きを付けて段落(pタグ)に表示している。

FetchのBodyのbodyプロパティからgetReader()メソッドで取得したReadableStreamデータのhtmlファイルなどをセレクターで分けたりして操作したい場合、先ずはTextDecoderで文字コードをByteからデコードしなくてはならない。TextDecoderの使い方はnew演算子でコンストラクタを作成する。引数に半角引用符付きで文字コードを入力するけれども空白だと初期値の「UTF-8」へデコードされる。次いでtextデータのときと同じようにDOMParserでパースする。TextDecoderでデコードしてもReadableStreamデータはDOMStringに変わるだけなので、相応のDocumentへ変換しながら元のファイルのDOMツリーの状態に戻さないと所定のプログラミングを受け付けない。

コメント

注目の投稿

日付: 

YouTubeの収益化を目指す絶望的に気が遠くなる未来

イメージ

些細な日常の人気記事

ナサニエル・ホーソーンの若いグッドマン・ブラウンの原文と注解

イメージ

アメリカの英語の小説、 ナサニエル・ホーソーンの 若いグッドマン・ブラウン を日本語に翻訳 しながら分からない単語や熟語を調べたので、英語の学習用に原文に沿って段落毎に掲載する。 取り上げる言葉の語彙力としてはおよそ日本の高校を卒業した水準以上、すなわち英検二級かTOEIC7...

ナサニエル・ホーソーンの若いグッドマン・ブラウンの日本語訳

イメージ

十九世紀のアメリカの作家、小説家の ナサニエル・ホーソーン の小説の 若いグッドマン・ブラウン (1835)の日本語訳を行った。一つの文学作品として人間の洞察力に富んだ優れた内容を持つだけではなく、表現も意義深いから外国語の英語の聞き取りと読み取りの教材としても最適だと感じる。 ...

ヘンリー・ローソンの家畜追いの妻の日本語訳

イメージ

十九から二十世紀のオーストラリアの作家、詩人で小説家の ヘンリー・ローソン の小説の 家畜追いの妻 (1892)の日本語訳を行った。一つの文学作品として人間の洞察力に富んだ優れた内容を持つだけではなく、表現も意義深いから外国語の英語の聞き取りと読み取りの教材としても最適だと感じる...

ジャパネットたかたの丸尾詩織の商品説明に気持ちが入っていて素晴らしい理由

イメージ

ジャパネットたかた のテレビショッピングを観ていて社員の丸尾詩織の商品説明の言葉が力強くてどんどん前に出て来るように聞こえるのが凄いと感じた。声が立体的に表現されているのは飛び出す絵本とか3D映像なんて印象まで与えるから他では経験できないほどの聴覚芸術が新たに生み出されたとも過言...