jQuery を使ってブラウザーで XML を処理する

いくつかの大きな落とし穴を避け、よく使われる Web アプリケーションの API のメリットを活用する

人気のある JavaScript ライブラリーである jQuery は、HTML を扱うための使い方が最もよく知られています。しかし意識して落とし穴に注意すれば、jQuery を XML の処理にも使うことができます。この記事では、jQuery を使って Atom Web フィード・フォーマットを処理する方法について説明します。Web フィードとしての XML はおそらく最もよく使われている XML フォーマットであり、Web 上で XML を使用して実現できる主なものです。しかし、そうしたフォーマットの大部分は XML 名前空間を使用しており、それによって jQuery などの一般的な多くの JavaScript ライブラリーに問題が起こります。

Uche Ogbuji (uche@ogbuji.net), Partner, Zepheira, LLC

Photo of Uche OgbujiUche Ogbuji は次世代の Web 技術によるソリューションを専門とする会社、Zepheira, LLCパートナーです。Ogbuji 氏は、XML その他のデータ統合サービスのオープンソース・プラットフォームである Akara の中心的開発者です。彼はナイジェリア出身のコンピューター・エンジニア兼ライターとして、米国コロラド州ボルダーに住み、そこで働いています。彼は詩やエッセイも書き、The Nervousbreakdown で詩を担当する副編集者です。彼に関して詳しくは、彼のブログである Copia を見てください。



2009年 12月 08日

XML は Web のための SGML ですが、XML コミュニティーが望むほど Web で大きな注目を集めてはいません。Web 上の XML として最も有望な XHTML は、政治的な駆け引きや Design by Committee (委員会による設計) の影響を受け続けてきました。また他の大掛かりで技術的に妥当な仕様 (XForms や SVG など) は遅々として採用が進みません。Web での XML の成功は、時として予期せぬ方向に現れます。その一例が、各種 RSS や Atom などの XML フォーマットの Web フィードが一般的になったことです。

よく使われる頭字語

  • Ajax: Asynchronous JavaScript + XML
  • API: Application Programming Interface
  • CSS: Cascading StyleSheets
  • DOM: Document Object Model
  • HTML: HyperText Markup Language
  • RSS: Really Simple Syndication
  • SGML: Standard Generalized Markup Language
  • SVG: Scalable Vector Graphics
  • URI: Uniform Resource Identifier
  • URL: Uniform Resource Locator
  • W3C: World Wide Web Consortium
  • XHTML: Extensible HyperText Markup Language
  • XML: Extensible Markup Language

Web 上でどのような技術を利用する場合でもそうですが、XML を Web 上で利用する場合でも、その中心となる要素はブラウザーです。しかし Web 上での XML 処理に関する議論では、そのほとんどがサーバー・サイドに焦点を当てています。私は Firefox と XML について記したこの developerWorks の一連の記事 (「参考文献」を参照) の中で、Firefox をブラウザーとして使用して XML を扱うさまざまな方法について説明しました。残念ながら、すべてのブラウザーに対応できるように XML を処理することは、すべてのブラウザーに対応できるように HTML を処理するよりも、さらに大変です。Web 上での XML 処理のほとんどがサーバー・サイドの比較的安全な領域に限られている一因は、そこにあります。

動的な HTML の開発を行う人達の多くは、ブラウザーの違いに対する処理やブラウザーごとに異なるスクリプトの動作にうんざりしています。しかし優れた JavaScript ライブラリーがいくつか登場したことにより、開発者の作業が楽になりました。そうしたライブラリーの中で最もよく使われているものが、この developerWorks でも何本かの記事で解説されてきた jQuery です。jQuery を使うと XML を処理することもできますが、そのためには巨大な落とし穴を避ける方法を学ぶ必要があります。この記事では、jQuery を使用して XML を処理するための実用的なシナリオを説明します。そして Atom Web フィードを扱いながら、jQuery で XML を処理するための有用なパターンを紹介し、残念とはいえ現実に起こりうる問題に対処する方法を説明します。この記事を読むためには、XML、XML 名前空間、HTML、JavaScript、そして jQuery ライブラリーを基本的に理解している必要があります (jQuery 入門用の記事については「参考文献」を参照してください)。

XML 名前空間の悲劇

まず、最大の問題から始めることにします。jQuery は XML 名前空間をまったく処理することができません。これは長年よく知られている問題であり、さまざまな人々が、満足するには程遠く、すぐに破綻する多種多様な回避策を考え出してきました。理想的な解決策は、jQuery が CSS Level 3 の名前空間セレクター (まだ W3C のワーキング・ドラフトにすぎません。「参考文献」を参照) をサポートすることです。そうすれば、以下のように新しい種類のセレクターを追加することができます。

@namespace ex url(http://example.com);
ex|quote { font-weight: bold }

1 行目は http://example.com に対する名前空間接頭辞の宣言です。そして 2 行目は新しい名前空間コンポーネントを使うタイプ・セレクターであり、宣言された接頭辞はパイプ文字によってローカル名から分離されています。これは残念ながら jQuery ではサポートされていません。そのため人々は名前空間を扱うために、ありとあらゆる細工をしています。

接頭辞が重要であると見なす

jQuery で XML と名前空間を扱うために最もよく使われる細工の 1 つは、名前空間を無視し、完全修飾子名 (接頭辞とローカル部分) で選択する方法です。

    $(xml).find("x\\:quote").each(function() {
      //process each node
    });

このコードは、jQuery の概念であるノードの名前 (DOM の nodeName プロパティー) によって選択を行います。このコードにはコロンが含まれていますが、コロンは jQuery セレクターの予約文字であり、バックスラッシュを使ってエスケープする必要があります。さらに、バックスラッシュは JavaScript ストリングの予約文字であり、二重にする必要があります。この細工は、名前空間が等しい文書が異なる接頭辞を使用している場合には通用しません。

属性フィルターを細工する

何人かの人達は、以下の方法のバリエーションで成功したと報告しています。この方法は nodeName という擬似属性に jQuery の属性フィルターを使用します。

    $(xml).find("[nodeName=x:quote]").each(function() {
      //process each node
    });

jQuery 1.3.x よりも前のバージョンでは、nodeName の直前に @ を追加します。しかしこの方法は、この前のセクション「接頭辞が重要であると見なす」の方法と同じ根本的な問題を持っており、実際の多くの名前空間のシナリオでは通用しません。私は以下のバリエーションを試してみました。こちらの方が理にかなっています。

    $(xml).find("[namespaceURI='http://example.com'][localName='quote']")
    .each(function() {
      //process each node
    });

しかし残念ながら、この方法はうまく行きません。

適切なプラグインを求めて

こうしたトラブルが起きるのは、すべて jQuery に問題があるからというわけではありません。DOM には getElementsByTagName や getElementsByTagNameNS といった、ノードを発見するための効率的なメソッドが用意されています。後者の getElementsByTagNameNS は名前空間を認識するように設計されており、名前空間 URI を受け付け、接頭辞を無視します。しかし残念なことに、getElementsByTagNameNS はすべてのブラウザーでサポートされているものの、Microsoft® Internet Explorer® ではサポートされていません。いずれにせよ、jQuery の目標は、そうしたブラウザーの違いに対応し、人々が苦労せずにすむようにすることです。弱々しいながら考えられる言い訳として、jQuery のセレクターは主に CSS をベースにしており、W3C CSS Level 3 の名前空間セレクターでさえ、まだ残念ながらワーキング・ドラフの段階を通過していません。jQuery のバグ番号 #155「Get Namespaced Elements in XML Documents (XML 文書で名前空間付き要素を取得する)」(「参考文献」を参照) は、これらの問題を取り上げていますが、3 年たっても対応されていません。

Ryan Kelly はこの問題に突き当たり、XML 名前空間のセレクター用に jquery.xmlns.js という jQuery プラグインを作成するという勇敢な試みをしました (「参考文献」を参照)。このプラグインは以下のようなコードをサポートしようとしています。

$.xmlns["ex"] = "http://example.com";
$(doc).find("ex|quote").each(...);

1 行目は、このプラグインに対するグローバルな名前空間宣言です。グローバルである理由は、ベースとなる jQuery のメカニズムの制約によるものです。この方法によって、名前空間のスコープを設定するための典型的な jQuery イディオムの中に、グローバルではないブロックを提供することができます。残念ながら、私がこの拡張機能を使ったところ、成功する場合も成功しない場合もありました。必ず成功するようになること、そしてこの方法が最終的に jQuery に採用されることを願っています。

もっと単純なプラグイン

私が最終的に選択したソリューションは、単純なプラグインを作成する方法でした。このプラグインは jQuery セレクターに関しては何も特別なことをしませんが、新しいフィルターを追加します。このフィルターに対して名前空間とローカル名を直接渡し、一致するノードのみに結果セットを制限するのです。この使い方は以下のとおりです。

  $(xml).find('*').ns_filter('http://example.com', 'quote').each(function(){
  .each(function() {
    //process each node
  });

ns_filter は私が作成した特別なフィルターです。find('*') も実行する必要がある点はスマートではないと思えるかもしれません。これよりも単純なバリエーションとして、以下も考えられます。

  $(xml).find('quote').ns_filter('http://example.com').each(function(){
  .each(function() {
    //process each node
  });

しかしこの方法は実際には使えません。jQuery は find('quote') のようなクエリーを名前空間に依存しない方法で (つまりローカル名セレクターとして) 扱うとは限らないからです。私のフィルターの実装については、次のセクションで XML 処理用に jQuery を設定する汎用システムの一部として説明します。私はこのフィルターのテストを、Mac OS X Snow Leopard 上で Firefox 3.5.5 と Safari 4.0.4 を使って、また Windows® XP 上で最近のバージョンの Internet Explorer 7 と Internet Explorer 8 を使って行いました。

jQuery XML ワークベンチ

名前空間の問題は、jQuery は結局 HTML ツールであるという事実による 1 つの症状にすぎません。私はこのことから、XML の処理に jQuery を使うための最も有用なパターンは、XML 文書用の HTML ワークベンチを作成することだと気付きました。このワークベンチが、ブラウザーの種類に依存しない信頼性の高い方法でスクリプトを呼び出し、必要な回避策 (例えば XML 名前空間のための回避策など) を設定するのです。このワークベンチ・パターンを使用すると、ブラウザー・ベースの XML 処理のためのパターンや手法の準備やテストをすることができ、さらには、このワークベンチをブラウザー・ベースのアプリケーション自体の土台として使うこともできます。

リスト 1 (quotes.html) は、このワークベンチを使用した HTML の簡単な例です。この例では、いくつかの引用語句を XML ファイルから動的にロードしています。

リスト 1. (quotes.html) jQuery XML ワークベンチを使用した HTML の例
<html>
        <head>
                <title>jQuery XML workbench</title>
                <script type="text/javascript" src="jquery.js"></script>
                <script type="text/javascript" src="workbench.js"></script>
                <script type="text/javascript" src="quotes.js"></script>
                <!-- Put the XML file or URL in the href attribute below: -->
        <link href="quotes1.xml" type="application/xml" rel="target_XML" />
        </head>
        <body>
        <h1>A few quotations for your enjoyment</h1>
        <div id="update-target"><ol></ol></div>
        </body>
</html>

script 要素は、jQuery そのものや、ワークベンチの JavaScript、そしてアプリケーション専用のスクリプトをロードするために必要です。また、target_XML を使って取得される XML ファイルを特定するための link 要素も必要です。複数の XML ファイルを扱う必要がある場合には、このワークベンチの設定を容易に拡張することができます。リスト 2 (workbench.js) は、このワークベンチのスクリプトです。

リスト 2. (workbench.js) jQuery XML ワークベンチの JavaScript
/*
workbench.js
*/
// The jQuery hook invoked once the DOM is fully ready
$(document).ready(function(){ 
        // Get the target XML file contents (Ajax call)
        var fileurl = $("link[rel='target_XML']").attr('href');
    $.ajax({
        url: fileurl,
        type: "GET",
        dataType: "xml",
        complete: xml_ready,
        error: error_func
     });
});

// Callback for when the Ajax call results in an error
function error_func(result) {
    alert(result.responseText);
}

// ns_filter, a jQuery extension for XML namespace queries.
(function($) {
  $.fn.ns_filter = function(namespaceURI, localName) {
    return $(this).filter(function() {
        var domnode = $(this)[0];
        return (domnode.namespaceURI == namespaceURI && domnode.localName == localName);
    });
  };

})(jQuery);

ワークベンチのコードには十分なコメントを付けてありますが、ここでいくつか注記を追加しておきます。名前空間フィルターの関数は、このリストの最後にあります。最初の関数はおなじみの jQuery フックであり、メイン・ページの DOM の準備が完全に整うと呼び出されます。この関数は対象となる XML の URL を取得し、そのファイルをロードするために Ajax 呼び出しを行います。ここで、dataType: "xml" に注目してください。dataType: "xml" は Ajax メカニズムに対し、レスポンスとして返される文書を XML として構文解析するように指示しています。dataType: "xml" はエラーがある場合には error_func コールバックを呼び出し、それ以外の場合には、アプリケーションの動作を実行するためにユーザーが提供する、xml_ready コールバックを呼び出します。xml_ready コールバックによって結果の構造を取得します。この構造から、responseXML プロパティーの形で XML を抽出します。リスト 3 (quotes.js) は、この場合のアプリケーションのコードです。

リスト 3. (quotes.js) 動的な引用句ビューアーのアプリケーション・コード
/*
quotes.js
*/
function xml_ready(result){
    var xml = result.responseXML;

        //Make sure the target area for inserting data is clear
        $("#update-target ol").empty();
    $(xml).find('*').ns_filter('http://example.com', 'q').each(function(){
        var quote_text = $(this).text()

        $('<li></li>')
            .html(quote_text)
            .appendTo('#update-target ol');
    }); //close each(
}

リスト 4 (quotes1.xml) は引用句のリストの XML ファイルです。

リスト 4. (quotes1.xml) 引用句のリストの XML ファイル
<?xml version="1.0" encoding="utf-8"?>
<x:quotes xmlns:x='http://example.com'>
  <x:q>Words have meaning and names have power</x:q>
  <x:q>Sticks and stones will break my bones, but names will never hurt me.</x:q>
  <x:q>The beginning of wisdom is to call things by their right names.</x:q>
  <x:q>Better to see the face than to hear the name. </x:q>
</x:quotes>

私が x 接頭辞を使っていることに注目してください。これは理論的には、先ほど触れた接頭辞ベースの細工の 1 つを試そうとしていることを意味します。しかしその細工をしたとすると、その細工は、引用句ファイルを (名前空間がリスト 4 と 100% 等価な) リスト 5 (quotes2.xml) や同じ Canonical XML で置き換えると機能しなくなります (「参考文献」を参照)。

リスト 5. (quotes2.xml) リスト 4 と等価な引用句のリストの XML ファイル
<?xml version="1.0" encoding="utf-8"?>
<quotes xmlns='http://example.com'>
  <q>Words have meaning and names have power</q>
  <q>Sticks and stones will break my bones, but names will never hurt me.</q>
  <q>The beginning of wisdom is to call things by their right names.</q>
  <q>Better to see the face than to hear the name. </q>
</quotes>

リスト 1quotes2.xml を使用しても、まったく同じように適切に動作することがわかります。これは名前空間の処理にとって重要なテストです。図 1 は quotes.html をブラウザーで表示したものです。

図 1. jQuery XML ワークベンチを使用して表示した引用句
jQuery XML ワークベンチを使用して表示した (リスト 5 の) 引用句

Atom の XML を動的に表示する

jQuery で XML の名前空間を処理できるようになると、RSS や Atom などの Web フィード・フォーマットを始めとするさらに多くの有用な XML フォーマットを処理できるようになります。このセクションでは、jQuery XML ワークベンチを使用して Atom フィードの最新のエントリーを Web ページ上に表示します。リスト 6 は、このページの HTML です。

リスト 6. (home.html) 動的な XML をホストする Web ページ
<html>
        <head>
                <title>jQuery XML workbench</title>
                <script type="text/javascript" src="jquery.js"></script>
                <script type="text/javascript" src="workbench.js"></script>
                <script type="text/javascript" src="home.js"></script>
                <!-- Put the XML file or URL in the href attribute below: -->
        <link href="atom1.xml" type="application/xml" rel="target_XML" />
        </head>
        <body>
        <h1>Caesar's home page</h1>
        <p>GALLIA est omnis divisa in partes tres, quarum unam incolunt Belgae,
    aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli
    appellantur. Hi omnes lingua, institutis, legibus inter se differunt.
    </p>

    <p>Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit.
    </p>

    <p>Horum omnium fortissimi sunt Belgae, propterea quod a cultu atque
    humanitate provinciae longissime absunt, minimeque ad eos mercatores saepe
    commeant atque ea quae ad effeminandos animos pertinent important,
    proximique sunt Germanis, qui trans Rhenum incolunt, quibuscum continenter
    bellum gerunt. Qua de causa Helvetii quoque reliquos Gallos virtute
    praecedunt, quod fere cotidianis proeliis cum Germanis contendunt, cum aut
    suis finibus eos prohibent aut ipsi in eorum finibus bellum gerunt.</p>

        <h2>My <a href="feed.xml">Web feed</a></h2>
        <div id="update-target"></div>
        </body>
</html>

リスト 7 (atom1.xml) は参照対象の Atom ファイルです。

リスト 7. (atom1.xml) サンプルの Atom ファイル
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"
      xml:lang="en"
      xml:base="http://www.example.org">
  <id>http://www.example.org/myfeed</id>
  <title>My Simple Feed</title>
  <updated>2005-07-15T12:00:00Z</updated>
  <link href="/blog" />
  <link rel="self" href="/myfeed" />
  <author><name>Uche Ogbuji</name></author>
  <entry>
    <id>http://www.example.org/entries/1</id>
    <title>A simple blog entry</title>
    <link href="/blog/2005/07/1" />
    <updated>2005-07-14T12:00:00Z</updated>
    <summary>This is a simple blog entry</summary>
  </entry>
  <entry>
    <id>http://www.example.org/entries/2</id>
    <title />
    <link href="/blog/2005/07/2" />
    <updated>2005-07-15T12:00:00Z</updated>
    <summary>This is simple blog entry without a title</summary>
  </entry>
</feed>

リスト 8 は home.js であり、このワークベンチにマウントされた動的なアプリケーション・コードを含んでいます。

リスト 8. (home.js) ホームページに Web フィードを表示するためのアプリケーション・コード
/*
home.js
*/
var ATOM_NS = 'http://www.w3.org/2005/Atom';

function xml_ready(result){
    var xml = result.responseXML;
        //Make sure the target area for inserting data is clear
        $("#update-target").empty();
    $(xml).find('*').ns_filter(ATOM_NS, 'entry').each(function(){
        var title_elem = $(this).find('*').ns_filter(ATOM_NS, 'title').clone();
        var link_text = $(this).find('[rel="alternate"]')
                            .ns_filter(ATOM_NS, 'link')
                            .attr('href');
        var summary_elem = $(this).find('*').ns_filter(ATOM_NS, 'summary').clone();

        //Deal with the case of a missing title
        if (!title_elem.text()){
            title_elem = '[No title]';
        }

        //Deal with the case where rel='alternate' is omitted
        if (!link_text){
            link_text = $(this).find('*')
                                .ns_filter(ATOM_NS, 'link')
                                .not('[rel]')
                                .attr('href');
        }

        //Update the target area with the entry information
        $('<p></p>')
            .append(
                $('<a href="' + link_text + '"></a>')
                .append(title_elem)
            )
            .append(' - ')
            .append(summary_elem.clone())
            .fadeIn('slow') //bonus animation
            .appendTo('#update-target');
    }); //close each(
}

この場合にもファイルには十分なコメントを追加してありますが、特に強調しておきたい点がいくつかあります。まず、Atom の要素には多くのバリエーションが許容されており、その多くはオプションです。これはつまり、例外的なケースを何らかの形で処理する必要があるということです。ここではそうしたケースのなかでもよくある例として、必要なリンクに対して rel="alternate" というオプションが指定されている場合、そしてタイトルがオプションで指定されている場合、の 2 つの例について説明します。ご覧のとおり、jQuery はこうしたケースをさまざまに柔軟な方法で扱うので、こうした標準的でない XML フォーマットであっても扱うことができるはずです。場合によると、私は XML からメイン文書 (ホストの HTML) に XML の構造を直接コピーしていますが、それには少し注意が必要です。コピーする文書のノードを別の文書の中のノードに接続することがないように (そうした接続は誤りであり、DOM の例外 WRONG_DOCUMENT_ERR によって警告されます)、私が clone() メソッドを使っていることに皆さんは気付くと思います。ついでに、私は jQuery の fadeIn メソッドを使用し、追加されたコンテンツがゆっくりと視覚的にフェードインされるようにしました。図 2 は home.html をブラウザーで表示したものです。

図 2. 動的に追加された Web フィードのコンテンツを持つホームページ
動的に追加された Web フィードのコンテンツを持つ、シーザーのホームページ (テキストはリスト 6 から引用)

まとめ

jQuery での課題は、Web ブラウザーの違いに対処するための多種多様な細工や回避策をどうパッケージ化するかに尽きます。この記事で紹介した XML ワークベンチは、XML を扱う必要がある人達に対して再利用可能なツールを提供するための第一歩です。この記事では、その最大の問題の 1 つが名前空間の扱い方であることを説明しました。そのハードルを越えさえすれば、jQuery は、XML によって非常に適切に表現されたさまざまな種類の標準的でない文書を扱うためのツールとなります。Web フィードを処理するために作成されたこの手法が、いかに容易にブラウザーに表示される他の多くの XML フォーマットにも適用できるかということに皆さんも気付くと思います。

jQuery や jQuery に付随する回避策が不適当だとわかった場合、もう 1 つの選択肢は、より直接的に XML 処理を対象とした、Sarissa などの JavaScript ライブラリーを使うことです。Sarissa は、それだけで 1 本の記事として取り上げるほどの価値がありますが、jQuery ほど広くは使われておらず、また jQuery ほど容易に使用することはできません。


ダウンロード

内容ファイル名サイズ
Code listings for this articlecode.zip6KB

参考文献

学ぶために

製品や技術を入手するために

  • jQuery や多くのサポート・リソースを入手してください。これらを利用することで、HTML 文書のトラバース、イベント処理、アニメーション化、Ajax 操作などを単純化し、Web 開発を迅速に行うことができます。
  • Ryan Kelly による jquery.xmlns.js プラグインから目を離さないでください。このプラグインは CSS 3 の名前空間セレクターをサポートしようとしていますが、この記事の執筆時点では、もう少し改善が必要なようです。
  • Sarissa を使うことを検討してみてください。この JavaScript ライブラリーは名前空間のサポートを含め、正面から XML 処理を行おうとしています。Sarissa は jQuery ほど広く使われてはおらず、jQuery ほど普及していませんが、XML を重視するアプリケーションには魅力的な選択肢です。
  • IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2®、Lotus®、Rational®、Tivoli®、WebSphere® などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

  • XML zone discussion forums に参加してください。これらのフォーラムでは XML を中心に議論が行われています。
  • developerWorks blogs から developerWorks のコミュニティーに加わってください。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。プロフィールで選択した情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=XML, Open source, Web development
ArticleID=461858
ArticleTitle=jQuery を使ってブラウザーで XML を処理する
publish-date=12082009