QueryPath PHP ライブラリーの紹介

素早く簡単に XML と HTML を操作する方法

HTML、HTTP、XML の 3 つは、誰もが認める Web 技術の中心的存在ですが、PHP 開発者にとっては、この 3 つを操作するのは苛立たしい作業になりがちです。そこで、jQuery JavaScript ライブラリーの PHP 版として新たに登場したQueryPath ライブラリーには、XML、HTML、HTTP を効率的に操作するための API が用意されています。QueryPath が提供するこの堅牢ながらも単純な API を使用すると、Web ページから Web サービス、SVG から SPARQL、そして RDF から Atom に至るまでの最新の Web 開発を PHP で行うことができます。この記事では QueryPath オブジェクトを作成する方法、XML および HTML をトラバースして操作する方法を説明し、最後に QueryPath を使用して Web サービス (Twitter) にアクセスする例を紹介します。

Matt Butcher, Senior Programmer, Palantir.net

Matt ButcherMatt Butcher は Web アプリケーション開発に 12 年以上の経験を持ちます。『Drupal 6 JavaScript and jQuery』、『Mastering OpenLDAP』をはじめ、5 冊の技術書の著者でもある彼は、これまで検索エンジン、組み込み Linux、コンテンツ管理システム、セマンティック・ネットワークに取り組んできました。心理学の学士号を持ち、現在は博士号の候補となっています。



2009年 4月 28日

はじめに

過去 15 年間、Web の飛躍的成長に最も貢献してきたのは HTML、HTTP、XML の 3 つの技術であると言えます。この 3 つの他にも、CSS や JavaScript、そして同様の技術を挙げることはできますが、リストのトップを飾るのは間違いなくこの「3 大技術」です。

Web 開発の世界では、PHP も注目を集めてきました。小さなホーム・ページから Yahoo! のような Web サイトまでが PHP を利用していますが、その主な理由は開発の容易さと Web を中心としたモデルにあります。それでも PHP を使って 3 大技術、特に XML を操作するとなると、そう簡単にはいきません。そこでこの記事では、QueryPath について学びます。この PHP ライブラリーは、以下の 2 つを実現することを念頭に置いて設計されています。

  • 単純さ。HTML、XML、HTTP を簡単に操作できるようにすること。
  • 堅牢性。この 3 つの技術を操作するための充実したツールを提供すること。

この記事では QueryPath オブジェクトの作成方法、XML と HTML のトラバースおよび操作方法、そして QueryPath によって Web サービス (サービスの例として Twitter を使用) にアクセスする方法を探っていきます。

まず、次のセクションで QueryPath ライブラリーとその設計について簡単に紹介します。


QueryPath

単純さを実現するために、QueryPath では簡潔な構文を使用します。メソッド名は短く、その内容をわかりやすく表現しています (text()append()remove() など)。ほとんどのメソッドは QueryPath オブジェクトを返すため、メソッド呼び出しをチェーンさせることができます。つまり、複数のメソッドを 1 つのシーケンスで呼び出せるということです。この仕組みは、流れるようなインターフェース (fluent interface) と呼ばれることもあります。JavaScript 開発者に親しみやすいように、QueryPath では jQuery のトラバース関数と操作関数、そして振る舞いのほとんどを実装しています。

一方、堅牢性を実現するために、QueryPath では XML および HTML コンテンツのロード、検索、読み取り、書き込みといった一般的な使用状況に対応するように設計されたツールを提供しています。しかしライブラリーのサイズがどうであろうと、1 つの汎用 API ではすべてのニーズに対応しきれません。この問題に対処するため、QueryPath には新しいメソッドを QueryPath に追加できる拡張メカニズムが用意されています。さらに、データベース・サポートや、テンプレート・サポート、そして XML を操作する機能などを追加するための拡張機能も QueryPath には組み込まれています。

ここで疑問に思うかもしれませんが、なぜ別の XML や HTML ツールが必要なのでしょうか。PHP V5 には DOM (Document Object Model) 実装と SimpleXML ライブラリーを含め、すでに多数の XML ツールがあります。それにも関わらず QueryPath が追加された理由は、簡単に言うと QueryPath は汎用的なツールとして設計されているからです。DOM API は複雑で扱いにくく、そのオブジェクト指向モデルは強力かもしれませんが、最も単純なタスクにでさえ数十行のコードを作成しなければなりません。その一方で、SimpleXML は多くのプログラミング・タスクには単純すぎます。XML が極めてありきたりなものでない限り、SimpleXML で文書をナビゲートするのは決して単純なことではありません。

QueryPath は、DOM の充実した機能と SimpleXML の単純さの程よい中間を取ろうという試みです。

要件

QueryPath は正真正銘の PHP ライブラリーです。そのため QueryPath を使うには、公式 Web サイトからダウンロードして PHP ライブラリー・パスに追加するだけで十分です。

QueryPath には最小限のシステム要件しかなく、DOM 拡張が有効になっている限り、QueryPath はPHP V5 で機能します。PHP V5 のほとんどのディストリビューションは何もしなくてもこの要件を満たします。QueryPath は長い間非推奨となっている PHP V4 についてはサポートしません。


QueryPath チェーンの構造

標準的な QueryPath の使用方法で中心となっているコンセプトには、以下の 4 つがあります。

  • QueryPath オブジェクトは単一の XML または HTML 文書と関連付けられます。
  • QueryPath は文書に対してクエリーによる検索を行うことが可能で、文書内で一致したものを識別します。
  • QueryPath は文書を操作することができます。文書の構成部分を新しく追加したり、既存の構成部分を変更したり、あるいは不要になった部分を削除したりすることができます。
  • 複数の QueryPath メソッドをチェーンさせ、まとまった 1 つのシーケンスで多数の操作を実行することができます。わずか数行のコードで、文書をロードしたり、文書に対して構文解析や、クエリーによる検索、変更、そして書き込みを行ったりすることができます。

リスト 1 のコードに、このすべてのポイントをまとめます。

リスト 1. 基本的な QueryPath チェーン
<?php
require 'QueryPath/QueryPath.php';

qp('sample.html')->find('title')->text('Hello World')->writeHTML();
?>

上記の例に必要なライブラリーは唯一、QueryPath/QueryPath.php だけです。QueryPath 拡張機能をロードしているのでない限り、このファイルを組み込みさえすれば、QueryPath を使用することができます。

PHP のオブジェクト構文

これまで手続き型言語を扱ってきた PHP 開発者にとっては、PHP のオブジェクト指向の構文には馴染みがないかもしれません。オブジェクトには関数が含まれている場合がありますが、これらの関数はメソッドと呼ばれます。オブジェクトのメソッドを呼び出すには、オブジェクト演算子 (->) を使用します。

このサンプル・コードでは、次に続く行が QueryPath チェーンです。このチェーンが実行する操作は以下のとおりです。

  1. sample.html 文書を指す QueryPath オブジェクトを新規に作成します。qp() が実行されると新規 QueryPath オブジェクトが作成され、このオブジェクトが文書をロードして構文解析します。
  2. find() メソッドでは、CSS (Cascading Style Sheet) 3 のセレクター、title を使用して、文書に含まれるすべての <title/> 要素を検索します。

    有効な HTML 文書内では、文書の先頭にある単一の <title/> 要素だけが突き合わせられます。

  3. タイトルのテキスト値を ‘Hello World’ に設定します。この操作が実行されると、タイトルの子ノードが CDATA (文字データ) ストリング ‘Hello World’ に置き換えられ、既存のすべてのコンテキストは破棄されます。
  4. writeHTML() メソッドによって文書全体を標準出力に書き込みます。

qp() ファクトリー関数は CSS セレクターを 2 つ目のパラメーターとしてオプションで取るため、上記のサンプル・コードは実際にはもう少し短くすることができます。リスト 2 に、短縮したバージョンを記載します。

リスト 2. 基本的な QueryPath チェーンの短縮バージョン
<?php
require 'QueryPath/QueryPath.php';

qp('sample.html', 'title')->text('Hello World')->writeHTML();
?>

sample.html が必要最小限の HTML 文書だとすると、上記 (リスト 1 またはリスト 2 ) の結果はリスト 3 のようになります。太字の行に、この例で設定したタイトルが含まれます。

リスト 3. 生成された HTML の例
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
	<title>Hello World</title>
</head>
<body>
</body>
</html>

この 2 つの単純な例から、QueryPath で実行可能な一般的なタスクがわかるはずです。この後のセクションで一連のメソッドについて検討した後、最後にこれらのビルディング・ブロックを組み立てて単純な Web サービス・クライアントを作成します。


qp() ファクトリー関数

QueryPath ライブラリーで最もよく使われる関数と言えば、qp() ファクトリー関数です。基本的に、この関数は新規 QueryPath オブジェクトを作成します。つまり、この関数は従来のコンストラクターの代わりとして使用されるということです。

オブジェクト指向デザイン・パターンをよくご存知の方は、qp() をファクトリー・パターンの変形であると理解するかもしれません。ビルダー・メソッドを持つファクトリー・クラスを定義する代わりに、QueryPath では直接関数を使います。この手法は入力の手間を省くだけでなく (これは、メソッドをチェーンする際に重要な点となります)、QueryPath をほとんど jQuery と同じように使用できるようになることから、jQuery に馴染みがある開発者にとっては学習曲線が縮まることになります。

QueryPath オブジェクトは単一の XML または HTML 文書と関連付けられます。QueryPath オブジェクトが作成されると、オブジェクトに文書がバインドされます。qp() 関数が取る引数は最大 3 つで、そのすべてがオプションです。これらの引数は以下のとおりです。

文書
ファイル名、URL、XML ストリング、HTML ストリング、DOMDocument、DOMElement、SimpleXMLElement にすることも、DOMElements の配列にすることもできます。何も指定されない場合、QueryPath は操作対象として空の XML 文書を作成します。
CSS3 セレクター
この引数が指定された場合、QueryPath は文書のロード時に、指定されたセレクターを使用して文書に対してクエリーによる検索を行います。
オプションの連想配列
この引数は、QueryPath の特定インスタンスに複雑な構成パラメーターのセットを渡す方法となります。API リファレンスに、この連想配列で渡せるオプションについての詳細が記載されています。

XML と HTML の違い

QueryPath は XML と HTML の両方を扱いますが、この 2 つのフォーマットにはいくつかの違いがあります。QueryPath は使用されているフォーマットを自動的に検出し、そのフォーマットに順応します。XHTML (XML での HTML 実装) は XML として扱われます。

qp() が最初の引数にこれほど多様なタイプのデータを取るのは、QueryPath オブジェクトを作成しやすくするためです。QueryPath をファイル名または URL で始めると、文書がロードされます。XML または HTML のストリングが渡されると、QueryPath はそのコンテンツを構文解析します。そしてもちろん、XML 文書のオブジェクト表現としてよく使われる DOM および SimpleXML で文書を受け取ることもできます。リスト 4 に、XML が含まれるストリングを qp() 関数で構文解析する方法を示します。

リスト 4. XML ストリングからの QueryPath オブジェクトの作成
<?php
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?><doc><item/></doc>';
$qp  = qp($xml);
?>

リスト 4 のコードを実行すると、$qp は内部で XML の構文解析済みの表現を指す QueryPath オブジェクトを参照することになります。前のセクションの例で渡したのはファイル名です。PHP が HTTP/HTTPS ストリーム・ラッパーを許容するように構成されている場合 (ほとんどの PHP V5 ディストリビューションでは、これが標準です)、以下のようにリモート HTTP URL をロードすることもできます。

リスト 5. URL からの QueryPath オブジェクトの作成
<?php
require 'QueryPath/QueryPath.php';

$qp = qp('http://example.com/file.xml');
?>

これにより、QueryPath で Web サービスにアクセスできるようになります (ストリーム・コンテキストは、3 つ目の qp() パラメーターを使用して渡せるため、接続設定を微調整することができます)。新しい文書を作成する際には、定型 HTML を追加するための近道があります。その方法は以下のとおりです。

リスト 6. QueryPath::HTML_STUB 定数の使用
<?php
require 'QueryPath/QueryPath.php';

$qp = qp(QueryPath::HTML_STUB);
?>

QueryPath::HTML_STUB 定数は、以下に記載する基本 HTML 文書を定義します。

リスト 7. QueryPath::HTML_STUB 文書
<?xml version="1.0"?>
<!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">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
	<title>Untitled</title>
</head>
<body></body>
</html>

このスケルトン文書を出発点とすることで、HTML をさらに素早く生成することができます。

これで、文書を指す新しい QueryPath オブジェクトの作成方法、そして単純な CSS セレクターについて理解できたはずです。次のセクションでは、QueryPath を使用して文書をトラバースする方法を説明します。

文書のトラバース

文書を開いた後は、対象のコンテンツを見つけるために文書内を上下左右に移動しなければなりません。QueryPath は、この移動が容易になるように設計されています。さまざまなトラバースのニーズに対応するため、QueryPath にはトラバースを行うためのメソッドがいくつか用意されていますが、そのほとんどは CSS3 セレクターを使用して目的のノードを検索することができます。

図 1. 重要な QueryPath トラバース・メソッド
重要な QueryPath トラバース・メソッド

図 1 は、一般的に使用されるトラバース関数の要点をまとめたものです。以下の表で、それぞれの関数について説明します。ここに記載している以外にもトラバース・メソッドはありますが、この表の関数を使用すれば一般的なニーズのほとんどに対応することができます。

表 1. 一般的なトラバース・メソッド
メソッド説明CSS セレクターの引数としての使用
find()セレクターと一致する (現在選択されているノードの下にある) 要素を選択
xpath()指定された XPath クエリーと一致する要素を選択不可 (代わりに XPath クエリーを使用)
top()文書要素 (ルート要素) を選択不可
parents()祖先要素を選択
parent()直接の親要素を選択
siblings()すべての兄弟要素 (前後の兄弟両方) を選択
next()次の兄弟要素を選択
nextAll()現在の要素の後にあるすべての兄弟要素を選択
prev()現在の要素の直前にある兄弟要素を選択
prevAll()現在の要素の前にあるすべての兄弟要素を選択
children()現在の要素の直下にある子要素を選択
deepest()最下層にある要素または現在の要素の下にあるすべての要素を選択不可

QueryPath の多くのメソッドでは、引数にクエリーを取ることで、選択項目をさらに詳細に指定することができます。表 1 の 3 列目に記載されているように、これらのメソッドのほとんどすべてが CSS3 セレクターをオプションの引数として取ります (xpath() 関数は CSS3 セレクターの代わりに XPath クエリーを引数に取ります)。CSS3 セレクターによるクエリーを引数として取らないのは、top() および deepest() だけです。

トラバースがどのように機能するかを説明する、もう 1 つの単純な例を取り上げます。例えば、以下のような XML 文書があるとします。

リスト 8. 単純な XML 文書
<?xml version="1.0"?>
<root>
  <child id="one"/>
  <child id="two"/>
  <child id="three"/>
  <ignore/>
</root>

<root/> 要素には 4 つの子要素があります。そのうちの 3 つは <child/> という名前で、残りの 1 つは <ignore/> という名前です。QueryPath クエリーを使えば、<root/> の 4 つすべての子要素を選択することができます。

リスト 9. すべての子要素の選択
<?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
  <child id="one"/>
  <child id="two"/>
  <child id="three"/>
  <ignore/>
</root>';

$qp = qp($xml, 'root')->children();
print $qp->size();
?>

children() メソッドは <root/> 要素の直接の子をすべて選択します。QueryPath オブジェクト内の一致する項目数を出力する最後の行によって、4 が出力されます。

今度は、3 つの <child/> 要素を選択し、<ignore/> 要素は選択から除外しなければならないとします。その場合、リスト 10 の方法を使えます。

リスト 10. フィルターを使用したクエリー
<?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
<child id="one"/>
<child id="two"/>
<child id="three"/>
<ignore/>
</root>';

$qp = qp($xml, 'root')->children('child');

print $qp->size();
?>

最後の print 文は、QueryPath が現在選択している項目の数を出力しますが、この場合は 3 を返します。内部では、QueryPath がこの 3 つの一致を追跡し、現在のコンテキストとして保存します。この後、さらにクエリーを実行する場合には、クエリーはこの 3 つの要素から始まります。また、データを追加する場合にも、そのデータはこの 3 つの要素に追加されることになります。

CSS セレクター

CSS 属性

CSS3 セレクターはいくつかの属性を特殊な属性として扱います。これに該当するのは、それぞれに専用のセレクター構文を持つ id 属性と class 属性です。他の XML 技術とは異なり、XML DTD やスキーマがこの 2 つの属性を特殊なものとして指定する必要はありません。そうした指定がなくても CSS3 セレクター・エンジンではこれらの属性を単に特殊な属性として扱います。

CSS セレクターは、スタイルを適用する要素を選択する CSS の書式の一部ですが、スタイル・シートのコンテキスト以外で使用することもできます。QueryPath はセレクターを問い合わせ言語の一部として使用し、CSS3 セレクターの標準に記述された機能セットをサポートします。

QueryPath では CSS セレクターが大きな役割を果たします。前のセクションの表では、10 個の関数 (メソッド) が CSS セレクターを引数として取っていますが、この記事でこれまで使用したセレクターは単なるタグ名のクエリーに過ぎません。CSS3 セレクターには、今までの例からは想像つかないほどの威力があります。CSS3 セレクターについての詳細な説明はこの記事ではしませんが、表 2 に共通のセレクター・パターンの例を記載します。

表 2. 共通 CSS3 セレクター・パターン
セレクター・パターン説明突き合わせの例
pタグ名が <p/> に設定された要素を検索。<p>
.containerclass 属性が container に設定された要素を検索。<div class="container"/>
#menuid 属性が menu に設定された要素を検索。これは ID ベースの検索を行う方法です。<div id="menu"/>
[type="inline"]type 属性の値が inline に設定されている要素を検索。<code type="inline"/>
tr > th<tr> を直接の親要素として持つ <th> 要素を検索。<tr><th/></tr>
table td<table> 要素を祖先要素 (親要素あるいは、さらにその親要素) として持つ <td> 要素を検索。<table><tr><td/></tr></table>
li:first名前が <li/> に設定された最初の要素を取得。サポートされる疑似クラスは、:last:even:odd です。<li/>
RDF|seq<RDF:seq> 要素を検索。QueryPath には XML 名前空間の CSS3 セレクターが含まれます。名前空間のサポートは属性および要素にまで適用されます。<RDF:seq>

上記の共通セレクター・パターンを組み合わせて、以下のような複雑なセレクターを作成することもできます。

div.content ul>li:first

このセレクターは、content クラスのあらゆる <div/> を検索します。さらに div 内部ですべての番号なしリスト (<ul>) を調べ、リストごとに最初のリスト項目 (<li>) を返します。

一致する項目での繰り返し処理

文書をトラバースする際の 2 つの観点として、QueryPath が提供するメソッドと CSS3 セレクターのサポートについて学びました。3 つ目の観点となるのは、選択した項目の繰り返し処理です。

QueryPath オブジェクトはトラバース可能です。PHP 流に言うと、QueryPath オブジェクトをイテレーターとして扱えるということです。標準的な PHP ループ構造では、QueryPath オブジェクトが選択した要素をループ処理することができます。XML 文書から 3 つの要素を取得するリスト 10 の単純なクエリーを思い出してください。次の例では、このクエリーをベースとして使用します。

例えば、各項目を個別に処理したいときにはどうすればよいでしょうか。QueryPath はイテレーターとして使用できることから、個別の項目でも簡単に処理することができます。リスト 11 に一例を示します。

リスト 11. 選択した要素の繰り返し処理
<?php 
require 'QueryPath/QueryPath.php';

$xml = '<?xml version="1.0"?>
<root>
<child id="one"/>
<child id="two"/>
<child id="three"/>
<ignore/>
</root>';

$qp = qp($xml, 'root')->children('child');

foreach ($qp as $child) {
  print $child->attr('id') . PHP_EOL;
}
?>

foreach ループはその繰り返し処理のなかで、一致する要素のそれぞれを $child 変数に割り当てます。$child は単なる要素ではありません。これは、現行の要素を指す QueryPath オブジェクトです。そのため、通常の QueryPath メソッドをすべて、思いのままに使用することができます。

API を jQuery の API と同じようにしておくため、QueryPath ではアクセサーおよびミューテーター、つまりゲッターとセッターとして機能するメソッドをいくつか用意しています。引数に応じて、同じ 1 つのメソッドがデータを取得 (アクセス) する場合もあれば、データを変更 (ミューテート) する場合もあります。その一例は attr() 関数です。qp()->attr('name') とあれば name という名前の属性の値を取得する一方、qp()->attr('name', 'value') とあれば name 属性の値に value を設定します。この他にも、アクセサーとミューテーターの 2 つの役目を果たすメソッドとしては text()html()xml() などがあります。

繰り返し処理される項目はそれぞれ QueryPath オブジェクトにラップされるため、$child では標準的な QueryPath メソッドをすべて自由に使うことができます。上記の例では、要素の属性に対するアクセサー兼ミューテーター、attr() 関数を使用しています。

attr() メソッドは id という名前の属性の値を取得します。上記のコードによる出力は以下のとおりです。

リスト 12. リスト 11 のイテレーターの例による出力
one
two
three

QueryPath メソッド、CSS3 セレクター、そして繰り返し処理の手法を使って文書をトラバースする方法を学んだところで、次のセクションでは QueryPath を使って文書を変更する方法を説明します。


文書の操作

QueryPath は文書の検索に使用できるだけでなく、文書に対するデータの追加、変更、削除にも使用することができます。リスト 1 で QueryPath に備わった機能の一端を見てもらいましたが、参考までにもう一度、以下に記載します。

リスト 13. 基本的な QueryPath チェーン
<?php
require 'QueryPath/QueryPath.php';

qp('sample.html')->find('title')->text('Hello World')->writeHTML();
?>

この例では text() メソッドを使って <title/> 要素の中身を変更していますが、QueryPath には文書を変更するためのメソッドが 10 以上あります。図 2 に、いくつかのよく使用される変更メソッドがそれぞれどのように機能するかを示します。これらのメソッドはいずれも、データを追加または置換するものです。緑色で示したタグは、現在選択されている要素を表します。

図 2. 中身を追加または置換するための QueryPath メソッド
中身を追加または置換するための QueryPath メソッド

それぞれのメソッドは、通常は HTML または XML のフラグメントという形でストリング・データを引数に取り、そのデータを文書に挿入します。挿入されたデータは、アクセス対象およびその後の操作の対象としてすぐに使用することができます。

HTML および XML フラグメントの操作

上記の図に示したメソッドは、実際には 2 種類のメソッドに分類することができます。一方のメソッドは、任意の XML フラグメントを以下のように操作します。

append()現在選択されている要素 (複数可) の最後の子要素としてデータを追加
prepend()現在選択されている要素 (複数可) の最初の子要素としてデータを追加
after()現在選択されている要素 (複数可) の直後にデータを挿入
before()現在選択されている要素 (複数可) の直前にデータを挿入
html()HTML 文書内で、現在の要素 (複数可) の子に相当する内容を置換
xml()XML 文書内で、現在の要素 (複数可) の子に相当する内容を置換

上記の項目は、整形式 XML または HTML データのストリングが含まれる引数を想定します。リスト 14 は、html() メソッドを使った例です。

リスト 14. 基本的な QueryPath チェーン
<?php
require 'QueryPath/QueryPath.php';

qp($file)->find('div.content')->html('<ul><li>One</li></ul>');
?>

図 2 には remove() メソッドが記載されていませんが (削除操作を視覚的に表現するのは難しいため)、remove() は文書から要素を削除するメソッドです。remove() メソッドは、引数を指定せずに呼び出した場合には現在選択されている要素を削除しますが、他の多くの QueryPath メソッドと同じく、このメソッドは CSS3 セレクターをオプションの引数として取ります。セレクターを指定すると、そのセレクターと一致する項目が削除されます。

属性の操作

図 2 のもう一方の種類に分類されるメソッドは、要素に含まれる属性を操作します。この例で要素に含まれる属性を操作するメソッドは以下の 2 つです。

attr()選択されたすべての要素で、特定の属性の値を取得または設定します。
addClass()現在選択されているすべての要素にクラスを追加します。

属性に関連するメソッドは他にもあります。例えば、removeClass() はクラス名を引数として取り、要素から個々のクラスを削除します。removeAttr() は属性名を属性として取り、現在選択されている要素のすべてから指定の属性を削除します。

それではいよいよ、今まで説明したすべての基本機能を 1 つの興味深い例にまとめてみます。


例: QueryPath による Twitter の検索

Twitter は短いメッセージを投稿できるとともに、他の Twitter ユーザーのマイクロブログをフォローできる、人気の高いマイクロブロギング・サービスです。Twitter が提供する単純な Web サービスには、このプラットフォームに備わった機能の多くが現れています。

以下の例では QueryPath を使用して、Twitter のサーバー上で検索を行い、その結果を HTML として出力します。このようなツールを既存の Web サイトに追加すれば、興味のあるトピックに最新の Twitter アクティビティーが表示されるようになります。

Twitter の検索サーバーは標準 HTTP サーバーをリッスンし、(要求に応じて) 検索結果を Atom XML フォーマットで返すことができます。この記事の例では、QueryPath について触れている最新の 5 件の投稿を検索します。このような検索を実行してコンテンツを Atom フォーマットで返すには、必要な情報を URL にエンコードすればよいだけです。したがって、URL は http://search.twitter.com/search.atom?rpp=5&q=QueryPath となります。

太字で示した 3 つの構成部分は、このアプリケーションに合わせたパラメーターです。

.atomこの拡張子が含まれている場合、サーバーに Atom XML コンテンツを返すように指示します。
rpp=5RPP は、1 ページに表示される結果の件数です。ここでは、5 件の結果を返すように指定しています。デフォルトで、5 件の最新結果が返されます。
q=QueryPathこれがクエリーです。Twitter はこれよりも複雑な検索クエリーをサポートしますが、この簡単な例ではこれで十分です。

この URL がロードされると、Twitter は Atom フォーマットの XML 文書を返します。以下のリスト 15 に記載しているのは、返された文書を大幅に単純化したものです。ここには、直接興味の対象となる情報だけが記載されています (エントリーは 1 つしか記載していません)。

リスト 15. Twitter の検索によって返された XML からの抜粋
<?xml version="1.0" encoding="UTF-8"?>
<feed>
  <entry>
    <content type="html">
       Last night I added XSD schema validation and XSL
       Transformation (XSLT) support to &lt;b&gt;QueryPath&lt;/b&gt; (as
       extensions). Will commit them today.
    </content>
    <link type="image/png" rel="image" href="http://example.com/img.jpg"/>
    <author>
      <name>technosophos (M Butcher)</name>
      <uri>http://twitter.com/technosophos</uri>
    </author>
  </entry>
</feed>

リスト 16 に示す簡潔な QueryPath コードが検索を実行し、検索結果として返された XML を選別して文書を作成します。

リスト 16. QueryPath による検索結果として返された XML の処理
<?php
require 'QueryPath/QueryPath.php';

$url = 'http://search.twitter.com/search.atom?rpp=5&q=QueryPath';
$out = qp(QueryPath::HTML_STUB, 'body')->append('<ul/>')->find('ul');

foreach (qp($url, 'entry') as $result) {
  $title = $result->children('content')->text();
  $img = $result->siblings('link[rel="image"]')->attr('href');
  $author = $result->parent()->find('author>name')->text();
  $out->append("<li><img src='$img'/> <em>$author</em><br/>$title</li>");
}
$out->writeHTML();
?>

上記のコードを Web ブラウザーで実行したとすると、図 3 のような表示になります。

図 3. QueryPath による Twitter 検索結果の表示
QueryPath による Twitter 検索結果の表示

リスト 16 のコードは 14 行の長さで、作業はそのうち 9 行だけで行われます。これだけのコードで、どのようにして図 3 の表示に変換したのでしょうか。

$url 変数が保持するのは、前に説明した Twitter URL です。$out 変数が指すのは QueryPath オブジェクトで、このオブジェクトを使用して HTML を作成してクライアントに出力します。基本文書 (QueryPath::HTML_STUB) をベースに番号なしリストを追加し、(find() を使用して) その新しいリストを選択します。

このスクリプトで最も重要なのは foreach ループの行、つまり foreach (qp($url, 'entry') as $result) です。新規 QueryPath オブジェクトは、この行で作成されます。URL が渡されることから、QueryPath はリモート Atom 文書を取得して結果を構文解析します。さらに、セレクター entry が渡されるため、QueryPath は文書内のすべてのエントリーを選択します。文書のどの部分がこれに該当するかを把握するには、リスト 15 をもう一度見てください。URL に設定された rpp フラグに従って、返される文書には 5 つのエントリーが含まれることになります。この 5 つのエントリーのそれぞれが、リスト 15 の <entry/> のように表示されるはずです。

ループ内部では以下の 3 つのデータが取得されます。

$titleエントリーの内容
$img投稿したユーザーのプロファイル画像への URL
$author投稿したユーザーの名前

上記のそれぞれのデータを取得するために用いる QueryPath メソッドはさまざまにあります。例えば、$title を取得するには $result->children('content')->text(); を使用することができます。

text()html()xml() によるコンテンツへのアクセス

text() を使ってテキストを設定する方法は前に説明しました (リスト 1)。リスト 16 では、これと同じメソッドを使って情報を取得します。text() 関数はすべてのテキスト・コンテンツを返しますが、これには要素や他のノード・タイプは含まれません。コンテンツのすべてを取得するには xml() を使用するか、あるいは HTML 文書の場合には html() を使用してください。

このメソッドは最初にタグ名が content となっている子をすべて選択した後、検出されたノード内から CDATA テキストを取得します。すべてのエントリーは 1 つの <content/> 要素を持つことになります。

今度は画像の URL を取得しなければなりません。前のチェーンで <content/> 要素を選択したため、これが出発点となります。<content/> の兄弟で <link rel="image"/> のような要素を検索する必要がありますが、それにはセレクターを設定した siblings() 関数を使用します。次に attr() 関数を使って、要素に設定された href 属性の値を取得します。

最後に、<link/> 要素からその親まで戻り、find('author>name') を使用して作成者の名前を取得します (このメソッドの機能については、表 2 を参照してください)。その上で text() を使用すれば、作成者の名前のテキストを取得することができます。

foreach ループの繰り返し処理が終了するたびに、蓄積された HTML のフラグメントを、append() を使って QueryPath の $out に挿入します。

Twitter からの結果が繰り返し処理された後、$out->writeHTML(); で HTML 文書をブラウザーに出力すれば、このスクリプトは仕上がります。

以上のように、約 10 行のコードでリモート Web サービスとのインターフェースが取れました。QueryPath をこのような方法で利用すれば、HTTP と XML または HTML を使用するほとんどすべての Web サービスにアクセスすることができます。QueryPath に付属のサンプルを見ると、接続パラメーターの設定方法、SPARQL エンドポイントに対して SPARQL クエリーを実行する方法、そして複雑な複数の名前空間を持つ文書の構文解析方法もわかるはずです。QueryPath はこのように、Web サービスの操作に大きな可能性をもたらします。


まとめ

この記事では QueryPath ライブラリーの基本として、QueryPath オブジェクトの作成方法、文書のトラバース方法、コンテンツの操作方法を説明しました。さらに、人気の高い Twitter マイクロブロギング・サービスの Web サービス API と連動する簡単なサンプル・スクリプトも作成しました。

この記事では QueryPath ライブラリーの持つさまざまな可能性の一端を探っただけに過ぎません。例えば、ここではデータベース API について触れたに過ぎませんが、この API を使用して RDBMS サポートを QueryPath に統合することもできます。SQL の SELECT 文を実行し、その結果を独自の仕様に従ってマークアップを設定した HTML の表に直接マージできたとしたらどうでしょう。あるいは、データを構文解析してデータベースに直接挿入する XML インポーターを作成するという手も考えられます。

QueryPath には、この記事では触れてもいない機能もまだまだあります。マッパーやフィルターを使って、QueryPath データを変換あるいはフィルタリングするカスタム関数を QueryPath に実行させることも、QPTPL 拡張機能によって、データを事前定義した純粋な HTML テンプレートにマージすることもできます。さらに QueryPath はユーザー定義拡張機能もサポートします。単純なクラス定義を作成することで、独自のメソッドを QueryPath に追加することができます。

参考文献

学ぶために

  • QueryPath.org は QueryPath プロジェクトの公式 Web サイトです。
  • QueryPath のドキュメントに、詳細な API マニュアル、サンプル、チュートリアル、その他のリソースが用意されています。
  • QueryPath を生むことになった JavaScript ライブラリー、jQuery の詳細を学んでください。
  • W3C による CSS3 セレクター仕様を読んで、QueryPath がサポートする問い合わせ言語について学んでください。
  • QueryPath は W3C のXPath (XML Path Language) クエリーもサポートします。
  • 同じく W3C が標準化している DOM (Document Object Model) API についても読んでください。
  • 友だちや家族、同僚と通信して連絡を取り合うためのサービス、Twitter では Web サービス API を公開しています。
  • Twitter で QueryPath をフォローして、QueryPath 開発の最新情報を入手してください。
  • Matt Butcher が彼の TechnoSophos ブログに QueryPath 関連のニュースおよび記事を投稿しています。
  • PHP.net は、PHP 開発者にとって主要な情報源となっています。
  • Recommended PHP reading list」に目を通してください。
  • developerWorks ですべての PHP 関連記事を調べてください。
  • developerWorks の Twitter をフォローしてください。
  • IBM developerWorks の PHP project resources にアクセスして、PHP の腕を磨いてください。
  • ソフトウェア開発者を対象とした興味深いインタービューや討論については、developerWorks ポッドキャストをチェックしてください。
  • PHP でデータベースを使用するには Zend Core for IBM を調べてみてください。シームレスにすぐに使えて、インストールも簡単なこの PHP 開発および実動環境は、IBM DB2 V9 をサポートします。
  • developerWorks の Technical events and webcasts で最新情報を入手してください。
  • 世界中で近日中に予定されている IBM オープンソース開発者を対象とした会議、見本市、ウェブキャストやその他のイベントをチェックしてください。
  • オープンソース技術を使用して開発し、IBM の製品と併用するときに役立つ広範囲のハウツー情報、ツール、およびプロジェクト・アップデートについては、developerWorks Open source ゾーンを参照してください。
  • 無料の developerWorks On demand demos で、IBM およびオープンソースの技術と製品機能を調べて試してみてください。

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

  • QueryPath.org で最新の QueryPath バージョンをダウンロードしてください。
  • Drupal ユーザーには、Drupal 対応の正式 QueryPath モジュールがあります。
  • IBM ソフトウェアの試用版を使用して、次のオープンソース開発プロジェクトを革新してください。ダウンロード、あるいは DVD で入手できます。
  • IBM 製品の評価版をダウンロードしてください。または、IBM SOA Sandbox のオンライン試用版で、DB2®、Lotus®、Rational®、Tivoli®、および WebSphere® のアプリケーション開発ツールとミドルウェア製品を体験することもできます。

議論するために

  • developerWorks blogs から developerWorks コミュニティーに加わってください。
  • developerWorks PHP Forum: Developing PHP applications with IBM Information Management products (DB2, IDS) に参加してください。

コメント

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=Open source, Web development
ArticleID=395478
ArticleTitle=QueryPath PHP ライブラリーの紹介
publish-date=04282009