サーバー上のXMLファイルを読み込む

 それではAJaxの本命(?)であるXMLデータを読み込んで処理します。ここで読み込むXMLデータは以下のようになっています。XMLでは文字コードを指定できますが、ここでは標準的なUTF-8の文字コードとし、なおかつトラブルを起こさないために(勉強用なので)、日本語は一切使用せずに英数字のみのデータにしてあります。

ファイル名 : name.xml
<?xml version="1.0" encoding="UTF-8" ?>
<userlist>
<user>
<number>1</number>
<username>Furuhata</username>
</user>
<user>
<number>2</number>
<username>Takahashi</username>
</user>
<user>
<number>3</number>
<username>Hiramatsu</username>
</user>
</userlist>

 XMLデータは階層構造になっています。HTMLと比較しても曖昧な構造にはなっていません。HTMLでは適当にタグを記述してもブラウザがうまく処理してくれましたが、XMLの場合には適当にやってしまうと正しく処理されません。Firefox(ブラウザの名前です。mozillaのサイトからダウンロードできます)などではXMLファイルを表示できますが、データに問題がある場合には「XML パースエラー」のようにエラーが発生します。自分で手書きで作成することは少ないかもしれませんが、自分で作成したXMLデータの場合にはFirefoxやSafari, Operaなどでチェックすると良いでしょう。
 Ajaxで上記のようなXMLデータを読み込むにはresponseXMLを使います。responseXMLはプロパティでサーバーから送信されたXMLデータ内容が入っています。単なる文字を読み込む場合はresponseTextでしたが、XMLの場合にはresponseXMLを使えばよい、ということです。以下のプログラムはresponseXMLプロパティの内容をページ上に表示するものです。(サンプルを実行する)

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>サーバー上のXMLファイルを読み込む</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadXMLFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
$("result").innerHTML = httpObj.responseXML;
}else{
$("result").innerHTML = "<b>Loading...</b>";
}
}

// --></script>
</head>
<body>
<h1>サーバー上のXMLファイルを読み込む</h1>
<p>XMLファイルを読み込みます</p>
<form name="ajaxForm">
<input type="button" value="name.xmlファイルを読み込み" onClick="loadXMLFile('name.xml')"><br>
</form>
<div id="result"></div>
</body>
</html>


 上記のプログラムを実行するとページ上には[object XMLDocument]と表示されます。XMLデータの内容が表示されずに、XML文書オブジェクトですよ、となってしまいました。responseTextの場合は、データそのものだったので単純に表示できましたが、XMLの場合にはデータを処理するためのプログラムを記述しなければページ上に表示できません。ところで、どのようにすればXMLデータの内容を読み出してページ上に表示できるのでしょうか。
 まず、一番最初のデータであるnumberタグで囲まれた数字の1を読み出してみましょう(サンプルを実行する)。プログラムの一部分のみ抜粋すると以下のようになります。

xmlData = httpObj.responseXML;
numberListTags = xmlData.getElementsByTagName("number");
$("result").innerHTML = numberListTags[0].childNodes[0].nodeValue;

 一番最初の行でサーバーからのXMLデータを読み込んで変数xmlDataに入れます。次にXMLデータ内のタグにアクセスします。ここではnumberタグの内容を読み出せばよいので、xmlData.getElementsByTagName("number")とします。このようにするとnumberタグのデータが配列データとして返されます。numberListTags変数に結果を格納していますが、numberListTagsは配列になるのでnumberListTags[0]やnumberListTags[2]のようにして参照することができます。次にnumberタグのデータを読み込みます。一番最初のnumberタグなのでnumberListTags[0]になります。一番最初は1でなく0になります。次に内容を読み出しますが、numberタグ内の一番最初のデータ(ノードと呼ばれます)の内容なのでchildNodes[0]とします。あとはデータ(ノード)の内容を示すnodeValueプロパティを読み出せば、numberタグの一番最初のデータである1を読み出すことができます。
 それではname.xmlファイルに書かれているユーザーの数だけ繰り返し内容を表示してみましょう(サンプルを実行する)。XMLデータにはユーザーの数だけuserタグが書かれています。ユーザーの数だけ繰り返すにはuserタグのデータを配列として読み込みます。for命令を使ってuser配列の数だけ繰り返します。これは以下のようになります。

userListTags = xmlData.getElementsByTagName("user");
userLen = userListTags.length; // 登録されているユーザー数

 userListTagsにはuserタグの内容が配列として格納されます。lengthプロパティで配列数=userタグの数を読み出すことができます。今回の場合はユーザー数は3なので変数userLenには3が入ります。これで処理が3人分繰り返されることになります。

 表示するデータはnumberタグの数字とusernameタグのユーザー名なので、これらのデータへのアクセスを行うために以下のように配列として参照できるようにします。

numberListTags = xmlData.getElementsByTagName("number");
usernameListTags = xmlData.getElementsByTagName("username");

これでnumberタグへの参照が変数numberListTagsに、usernameタグへの参照が変数usernameListTagsに入ります。これらの配列の最初のデータ(ノード)を読み出し表示すればできあがりです。最初のデータ(ノード)はchildNodes[0]、そのノードの内容はnodeValueプロパティに入っています。これは前にも説明しました。あとは結果を入れる変数resultTextを用意し文字列として連結していきます。最後にresultText変数の内容をページ上に表示します。これで、めでたくXMLデータを表示させることができました。

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=shift_jis">
<title>サーバー上のXMLファイルを読み込み表示する</title>
<script type="text/javascript" src="xmlhttp.js"></script>
<script type="text/javascript"><!--
function loadXMLFile(fName)
{
httpObj = createXMLHttpRequest(displayData);
if (httpObj)
{
httpObj.open("GET",fName,true);
httpObj.send(null);
}
}
function displayData()
{
if ((httpObj.readyState == 4) && (httpObj.status == 200))
{
xmlData = httpObj.responseXML;
userListTags = xmlData.getElementsByTagName("user");
numberListTags = xmlData.getElementsByTagName("number");
usernameListTags = xmlData.getElementsByTagName("username");
userLen = userListTags.length; // 登録されているユーザー数

resultText = ""; // データの内容を表示するための変数
for(i=0; i<userLen; i++){
num = numberListTags[i].childNodes[0].nodeValue;
uname = usernameListTags[i].childNodes[0].nodeValue;
resultText = resultText + num + " : " + uname + "<br>";
}
$("result").innerHTML = resultText;
}else{
$("result").innerHTML = "<b>Loading...</b>";
}
}
// --></script>
</head>
<body>
<h1>サーバー上のXMLファイルを読み込み表示する</h1>
<p>XMLファイルを読み込み名前を表示します</p>
<form name="ajaxForm">
<input type="button" value="name.xmlファイルを読み込み" onClick="loadXMLFile('name.xml')"><br>
</form>
<div id="result"></div>
</body>
</html>


 上記サンプルでは最初のデータ(子ノード)にアクセスするためにchildNodes[0]と指定しましたが、最初のデータ(ノード)にアクセスすることは多くあるためchildNodes[0]の代わりにfirstChildを使用することができます。firstChildにしても全く同じように処理することができます(サンプルを実行する)。
 XML文書を利用することでテキストよりも柔軟にデータを処理することができます。XMLデータを扱うと処理速度は低下しますので、高速なレスポンスを要求されるようなサービスの場合にはテキストデータを利用した方がよいことがあります(2006.8.18日現在、Adobe Spryフレームワークを利用すると非常に手軽にXMLデータを扱うことができます)。
 
注釈:XML文書へのアクセスに関してはDOM(ドキュメントオブジェクトモデル)と同じ命令を利用することができます。

[10:サーバー上の画像ファイルを読み込むへ]
[目次へ]

(2005.12.30, 2006.8.18)