SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

CGI不可のサーバでもできるAjaxによるHTMLの動的な整形

Ajaxを利用したデータとプレゼンテーションの分離

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード ソースコード (12.9 KB)

HTMLからの脱却

 sample03ではコンテンツとなるHTMLを外部に分離し、sample04ではサイトの構造を表す設定を外部に分離しました。こうした作業は、プレゼンテーション技術としてのHTMLと、本質的なデータ部分を切り離そうという方向にあります。

 しかし、最も重要なデータ元である記事の本文がHTMLで書かれていることは、やはり柔軟性において問題を残します。例えば、記事を挿入する雛型のHTML文書の構造と、記事のHTMLの相性が合わないということがあります。とにかく表示できればそれでいいというサイトならば問題はないかもしれませんが、XHTML 1.0 Strictに準拠することが要求される場合、使えない要素や使ってほしくない非推奨の要素などが発生する可能性があります。

 こうした問題を踏まえ、XHTMLバージョンの変更やサイトのレイアウト、方針の変更に依存しないようにサイトを構築するには、記事をHTMLではなく、設定ファイルと同様にXMLで記述します。XMLで記述された記事をJavaScript+DOMでHTMLに変換して表示するという方法です。この方法であれば、プレゼンテーション(表示)とデータモデルを完全に分離することができ、高い柔軟性を確保することができます。

sample05 test.html
<?xml version=1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp">
 <head>
  <title>test</title>
  <script type="text/javascript">
function createRequest() {
 var req = null;
 if ("XMLHttpRequest" in window) {
  req = new XMLHttpRequest();
 }
 else if ("ActiveXObject" in window) {
  try {
   req = new ActiveXObject("Msxml2.XMLHTTP");
  }
  catch (e) {
   try {
    req = new ActiveXObject("Microsoft.XMLHTTP");
   }
   catch (e) {}
  }
 }

 return req;
}

var req;

function requestArticle(url) {
 req = createRequest();

 req.open("GET", url, true);
 req.onreadystatechange = req_readystatechange;
 req.send(null);
}

function req_readystatechange() {
 var divRightPanel = document.getElementById("rightPanel");
 if (req.readyState == 4) {
  if (req.status == 200) {
   setArticle(req.responseXML);
  }
  else {
   divRightPanel.innerHTML = "システムエラー:読み込めませんでした";
  }
 }
}

//要素内のテキストを抽出する
function getElementText(element) {
 var nodes = element.childNodes;
 var result = "";

 for(var i = 0 ; i < nodes.length ; i++) {
  var item = nodes.item(i);
  if (item.nodeType == 3) {
   result += item.nodeValue;
  }
 }
 return result;
}

//記事をrightPaneに出力する
function setArticle(articleDoc) {
 var divRightPanel = document.getElementById("rightPanel");
 var title; //タイトル(見出し)
 var author; //著者
 var copyright; //著作権

 //article要素の子要素を検出する
 var article = articleDoc.getElementsByTagName("article")[0];
 for(var i = 0 ; i < article.childNodes.length ; i++) {
  var item = article.childNodes.item(i);

  if (item.nodeType == 1) {
   if (item.nodeName == "title") title = getElementText(item);
   else if (item.nodeName == "author") author = getElementText(item);
   else if (copyright == "copyright") copyright = getElementText(item);
  }
 }

 divRightPanel.innerHTML = "<h1>" + title + "</h1>";

 //記事の本文を表すbody要素をHTMLに変換して出力
 var body = article.getElementsByTagName("body")[0];
 for(var i = 0 ; i < body.childNodes.length ; i++) {
  var item = body.childNodes.item(i);

  if (item.nodeType == 1) {
   if (item.nodeName == "p") {
    divRightPanel.innerHTML += "<p>" + getElementText(item) + "</p>";
   }
  }
 }

 //著者、著作権者情報を出力
 divRightPanel.innerHTML += "<p style=\"font-style:italic\">著者:"
  + author + "</p>";
 divRightPanel.innerHTML += "<p style=\"font-style:bold\">Copyright (c) "
  + author + "</p>";
}
  </script>
 </head>

 <body>
  <table border="0">
   <tr><td style="width:20%" valign="top">
    <p><a href="javascript:requestText('ajax0.xml')">はじめに</a></p>
   </td>
   <td style="width:80%" valign="top">
    <div id="rightPanel"></div>
   </td></tr>
  </table>
 </body>
</html>
sample05 ajax0.xml抜粋
<?xml version="1.0" encoding="UTF-8"?>
<article>
 <title>はじめに</title>
 <author>赤坂玲音</author>
 <copyright>赤坂玲音</copyright>

 <body>
  <p>
ここ最近、Web 2.0という言葉と共に(略)
  </p>
  <p>
では、Ajaxはそれほど敷居の高いものなのでしょうか。
質の高い開発集団や、高額な開発環境、またはサーバーなどの(略)
  </p>
 </body>
</article>

 sample05は、「ajax0.xml」をスクリプトで読み取り、XML文書を解析してHTMLに変換するというプログラムです。「test.html」を表示すると「はじめに」へのリンクが張られていますが、このリンクボタンを押すとrequestArticle()関数を呼び出して「ajax0.xml」をダウンロードする仕組みになっています。基本的な処理はsample03と同じですが、取得するデータがHTMLが書かれたテキストファイルではなく、純粋なXMLファイルである点が異なります。

 スクリプトからXMLHttpRequestオブジェクトを通じてサーバーに要求を行い、結果をreq_readystatechange()関数で受け取るとsetArticle()関数を呼び出して取得した記事を出力します。記事はHTML形式ではなく、独自に定めたXML形式で表されています。そのため、setArticle()関数の引数にはresponseXMLから取得したDocumentオブジェクトを渡しています。

 setArticle()関数はXMLの各要素を解析し、必要な値を受け取ってからHTMLとしてrightPanelに出力します。利用者にとっては、内部のデータ形式を意識する必要はなく、リンクを押したらコンテンツが表示されたように振る舞うことができます。

 記事のデータは「ajax0.xml」にXML形式で格納しています。このXML形式は、このサンプルのために即席で用意したものです。article要素をルート要素とし、article要素の子要素には、主題を表すtitle要素、著者を表すauthor要素、著作権者を表すcopyright要素、そして記事本文を表すbody要素を指定することができます。

 この方法であれば、コンテンツ本体だけではなく、コンテンツのメタデータなども柔軟に表現することができるようになります。記事には、短い文章で記事の要約を表すsummary要素を加えても良いでしょうし、記事のキーワードを表すtag要素などを加えても良いでしょう。それをどのように利用するかは、スクリプト側に委ねることができます。

 重要なのは、こうした記事の論理的な構造(データ)と、この情報を画面に表示する方法(プレゼンテーション)が分離されていることです。このサンプルでは「test.html」のスクリプトがHTMLに変換して表示していますが、これとは別のスクリプトから「ajax0.xml」を参照して2次元ベクタグラフィックス情報を表すSVG形式に変換するなど、異なる媒体に変換することも可能です。

 sample05のような規模になってくるとスクリプトでの処理が複雑になってきますが、XMLを別のデータに変換するXSLTなどの標準化された技術も存在しています。データの表現にXMLを用いることで、他の文書への変換や埋め込みが容易になり、または他のWebサイトとの相互運用も視野に入れることができるようになります。

最後に

 Webサイト全体の設計をデータモデル、ビジネスロジック、プレゼンテーションに分離して…という話になってくると趣味で開発する規模を超えてしまいますが、sample05を見ると、XMLがデータ、JavaScriptによる変換処理がビジネスロジック、そしてHTMLがプレゼンテーションを担当していると考えることができます。

 小規模な組織のWebサイトは、今も制限の強い共有レンタルサーバーを使っていることが多いと思います。データベースやサーバー側スクリプトを自由に使えない環境下で、データを抽象化し、ある程度の柔軟性や相互運用性を確保する手段として、前述したようなAjaxの応用があるのではないでしょうか。

 また、Ajaxは背景に膨大な量のデータを必要とするメディアをWebで実現する方法としても有効です。必要なときに、必要な部分だけをダウンロードして表示できます。例えば、小説サイトやノベル形式のゲームなどで、ページ移動を行わずに次のページを表示するリッチな演出が可能となります。

 Ajaxには複雑な一面もありますが、プロ集団でなければ作れないというものでもありません。本稿を通じて、学生の方や趣味で開発やWebサイト作りを楽しんでいる方に、Ajaxの実用について興味を持っていただければ幸いです。

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

赤坂 玲音(アカサカ レオン)

平成13年度「全国高校生・専門学校生プログラミングコンテスト 高校生プログラミングの部」にて最優秀賞を受賞。2005 年度~ Microsoft Most Variable Professional Visual Developer - Visual C++。プログラミング入門サイト WisdomSoft の管理人。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1015 2007/03/02 00:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング