jQueryでXMLを操作してみる2

以前に、XMLをjQueryで扱う勉強をした「jQueryでxmlを操作してみる」というエントリーを書いたのですが、なぜか今でも検索で見に来る人が多い…そんなにニーズがあるんだなーと、毎月驚いています。
今回は、先日エントリーした「ExcelをXMLで書き出したものをWEBで扱う時の注意」で書いたように、Excelで作ったデータをXMLで書き出し、そのデータを利用したサンプルでも一つ紹介してみようかなと思います。
XMLデータ
今回のXMLのデータは簡単に出来るようにExcelを使って書き出してみようと思います。Excelデータは簡易的に下記のように作ってみました。
このデータを保存するときにXML形式にして保存する。書き出して文字コードを加えたデータは下記のようなものになる。データは一部だけ表示しています。
■今回利用するXMLデータ(一部省略)
<?xml version="1.0" encoding="Shift-JIS" ?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
<DownloadComponents/>
<LocationOfComponents HRef="file:///\\"/>
</OfficeDocumentSettings>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
<WindowHeight>9120</WindowHeight>
<WindowWidth>11715</WindowWidth>
<WindowTopX>240</WindowTopX>
<WindowTopY>105</WindowTopY>
<ProtectStructure>False</ProtectStructure>
<ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>
<Worksheet ss:Name="テストシート">
<Table ss:ExpandedColumnCount="5" ss:ExpandedRowCount="27" x:FullColumns="1"
x:FullRows="1" ss:DefaultColumnWidth="54" ss:DefaultRowHeight="13.5">
<Column ss:StyleID="s21" ss:Width="27"/>
<Column ss:Width="63"/>
<Column ss:StyleID="s21" ss:Width="60"/>
<Column ss:Width="78.75"/>
<Column ss:Width="90"/>
<Row>
<Cell><Data ss:Type="String">ID</Data></Cell>
<Cell><PhoneticText xmlns="urn:schemas-microsoft-com:office:excel">メイ</PhoneticText><Data
ss:Type="String">ユーザー名</Data></Cell>
<Cell><Data ss:Type="String">パスワード</Data></Cell>
<Cell><Data ss:Type="String">メールアドレス</Data></Cell>
<Cell><PhoneticText xmlns="urn:schemas-microsoft-com:office:excel">デンワバンゴウ</PhoneticText><Data
ss:Type="String">電話番号</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">001</Data></Cell>
<Cell><Data ss:Type="String">aaa</Data></Cell>
<Cell><Data ss:Type="String">passa01</Data></Cell>
<Cell><Data ss:Type="String">a001@aa.aa</Data></Cell>
<Cell ss:StyleID="s21"><Data ss:Type="String">000-0000-0001</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">002</Data></Cell>
<Cell><Data ss:Type="String">bbb</Data></Cell>
<Cell><Data ss:Type="String">passa02</Data></Cell>
<Cell><Data ss:Type="String">a002@aa.aa</Data></Cell>
<Cell ss:StyleID="s21"><Data ss:Type="String">000-0000-0002</Data></Cell>
</Row>
<Row>
<Cell><Data ss:Type="String">003</Data></Cell>
<Cell><Data ss:Type="String">ccc</Data></Cell>
<Cell><Data ss:Type="String">passa03</Data></Cell>
<Cell><Data ss:Type="String">a003@aa.aa</Data></Cell>
<Cell ss:StyleID="s21"><Data ss:Type="String">000-0000-0003</Data></Cell>
</Row>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0.51200000000000001"/>
<Footer x:Margin="0.51200000000000001"/>
<PageMargins x:Bottom="0.98399999999999999" x:Left="0.78700000000000003"
x:Right="0.78700000000000003" x:Top="0.98399999999999999"/>
</PageSetup>
<Selected/>
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>24</ActiveRow>
<ActiveCol>5</ActiveCol>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
今回の作るサンプル
今回jQueryとXMLで作るサンプルはデータの見出しを全てドロップダウンにして、そこで選択したデータだけを表示させるという簡単なもの。↓こんな感じになる。簡易的な解説はスクリプト中のコメントにて。
■スクリプト
jQuery(function($){
//XMLデータの読み込み
$.ajax({
//XMLファイルの指定
url: '../xml/samplelist.xml',
type: 'GET',
dataType: 'xml',
timeout: 1000,
error: function(){
//XMLデータの読み込みに失敗した場合にアラート
alert("xmlファイルの読み込みに失敗しました");
},
success: function(xml){
//変数の初期化
var listitem,selectitem ="";
//エクセルデータの読み込み(XMLのデータはfindで取得)
$(xml).find("Row").each(function(i){
var select_text1 = $(this).next().find('Cell:eq(0) Data').text();
var select_text2 = $(this).next().find('Cell:eq(1) Data').text();
//ドロップダウンリストの中身
selectitem += '<option value="'+i+'">'+ select_text1
+':'+select_text2+'<\/option>';
});
//ドロップダウンリストの中身をHTML上に流し込む
$('form#select select').append(selectitem);
//表示の切り替え(ドロップダウンリスト選択)
$('form#select select').change(function(){
//取得アイテムの初期化
listitem = "";
//表示しているものを消す
$('div#samp-list').slideUp('slow');
//選択したID取得
var valId = $(this).val();
//表示アイテム取得(表示アイテム取得機能の呼び出し)
$(xml).find('Row:eq('+valId+')').each(datalist);
//セレクトしたものを表示(1秒後)
setTimeout(dataload,1000);
//取得IDの初期化
valId = "";
return false;
});
//XMLからアイテム取得する機能
function datalist(){
//next()をつけると2行目から取得
var item_text1 = $(this).next().find('Cell:eq(0) Data').text();
var item_text2 = $(this).next().find('Cell:eq(1) Data').text();
var item_text3 = $(this).next().find('Cell:eq(2) Data').text();
var item_text4 = $(this).next().find('Cell:eq(3) Data').text();
var item_text5 = $(this).next().find('Cell:eq(4) Data').text();
//HTMLの整理inputはreadonly
var prebox = '<div class="list">';
var pretext = '<p>データ<\/p>';
var ID =
'<form><dt>ID:<\/dt>'
+'<dd><input type="text" value="'+item_text1+'" readonly />'
+'<\/dd>';
var user =
'<dt>ユーザー名:<\/dt>'
+'<dd><input type="text" value="'+item_text2+'" readonly />'
+'<\/dd>';
var pass =
'<dt>パスワード:<\/dt>'
+'<dd><input type="text" value="'+item_text3+'" readonly />'
+'<\/dd>';
var mail =
'<dt>メールアドレス:<\/dt>'
+'<dd><input type="text" value="'+item_text4+'" readonly />'
+'<\/dd>';
var phone =
'<dt>電話番号:<\/dt>'
+'<dd><input type="text" value="'+item_text5+'" readonly />'
+'<\/dd>';
var endbox = '<\/form><\/div>';
//読み込んだデータをまとめる
listitem =
prebox + pretext + ID + user
+ pass + mail + phone + endbox;
//データの中身にundefinedがあったら削除
listitem = listitem.replace("undefined" , "");
};
//取得アイテムを表示する機能
function dataload(){
$('div#samp-list').slideDown('slow').html(listitem);
//フォーカスしたinputの色変え
$('input').focus(function(){
$(this).css({backgroundColor:'#e0ffff'});
//クリックしたら全選択
$(this).select()
});
$('input').blur(function(){
$(this).css({backgroundColor:'#ffffff'});
});
};
}
});
});
XML中のデータを取得するには、find()を使い、目的の部分だけを取得するにはeq()を使うと簡単に取得できる。上記のスクリプトのサンプル(デモ)は下記リンクにて。
XMLは同じドメイン上にあること
以前の補足にも書いたことだけど、XMLをjQueryで扱うときは、同じドメイン上においてある必要がある。別ドメインのXMLデータなどは読み込めないので注意。その場合はXMLではなく、JSONやJSONP形式のデータであれば読み込むことができる。クロスドメインで使用するかどうかなどの用途によって使い分けたほうがいいでしょう。


