レベル: 中級 中林 紀彦, ソフトウェア・エバンジェリスト, IBM
2009年 02月 01日 最近ではWeb APIや、Atom、RSSなどのフィードのほとんどがXML形式で公開されていますが、これらのXMLインスタンスを複数組み合わせてプログラミング言語だけでマッシュアップすることは、少々面倒なコーディングが必要になってしまいます。この記事では、インターネット上に公開されているさまざまなフィードやWeb APIをXQueryを使って簡単にマッシュアップする方法をご紹介します。
環境およびデータの準備
今回利用した環境は、以下の通りです。
-
DB2 9.5 Fixpack 3
-
IBM Data Studio Developer 2.1
IBM Data Studio Developerは必ず必要というわけではありませんが、DB2のオブジェクト操作やXQueryの作成や実行が簡単に行えるツールですのでお勧めです。インストールや簡単な利用方法は「IBM Data Studioクイック・スタート」を参考にして下さい。
今回はデータとしてRSS(XML)を利用するので、RSSを格納するためのテーブルを以下のように作成します。
リスト1 RSSテーブルの作成
create table rss (
id int not null primary key,
doc xml
);
|
また後半ではXMLをHTMLに変換するためにXSLTスタイルシートを利用しますので、XSLTスタイルシートを格納するためのテーブルもあわせて準備しておきます。
リスト2 XSLTテーブルの作成
create table xslt (
id int not null primary key,
doc xml
);
|
今回の素材として以下の3つのRSSを、前述のRSSテーブルに格納しておきます。
図1 RSSテーブルに登録された3つのRSS
データの登録などについては、「DB2 9.5 pureXML入門 - pureXMLサンプル・データベース」を参考にして下さい。
XQueryでRSSをマッシュアップする
ここからが本題ですが、複数のRSSをマッシュアップして日付の降順にそーとして新しいRSSを作り出すというRSSのマッシュアップをXQueryで実装してみたいと思います。
通常JAVAやPHPなどのプログラミング言語で実装しようとすると、DOMを使ってXMLインスタンスを操作するという方法が考えられますが、3つのXMLを1つに統合したり、ましては日付順にソートするということを実装しようと思ったら一苦労です。
では、XQueryを使うとどうでしょうか?以下に示すXQueryを見ていただくと理解できると思いますが、とても簡単です。
リスト3 RSSをマッシュアップするXQuery
XQUERY
<rss version="2.0">
<channel>
<title>RSSのマッシュアップ</title>
<description>複数のRSSをXQueryを使ってマッシュアップします</description>
{
for $c in db2-fn:xmlcolumn("RSS.DOC")/rss/channel/item
order by $c/pubDate descending
return $c
}
</channel>
</rss>
|
解説するまでもありませんが、for節で、3つ全てのXMLに含まれる“/rss/channel/item”を取り出しシーケンスを作ります。このシーケンスをorder節で日付(/rss/channel/item/pubDate)の降順にソートして、return節でitemノードを返すという非常にシンプルなXQueryです。
更にwhere節で条件を絞り込むという要件を加えたものが、以下のXQueryになります。
リスト4 タイトルで条件を絞り込むXQuery
XQUERY
<rss version="2.0">
<channel>
<title>RSSのマッシュアップ</title>
<description>複数のRSSをXQueryを使ってマッシュアップします</description>
{
for $c in db2-fn:xmlcolumn("RSS.DOC")/rss/channel/item
where fn:contains($c/title, 'XML')
order by $c/pubDate descending
return $c
}
</channel>
</rss>
|
XQuery標準のcontains関数を使って“/rss/channel/item/title”に「XML」が含まれるものだけを返すというXQueryになっています。
XSLTスタイルシートでRSSをHTMLに変換する
では最後にXSLTスタイルシートを使ってRSSからHTMLに変換してみたいと思います。DB2 9.5では「XSLTRANSFORM スカラー関数」が用意されていますので、前述のRSSをマッシュアップするXQueryと組み合わせることで、結果をHTMLに変換することが出来ます。
以下のようなXSLTスタイルシートを準備して、先に準備してたXSLTテーブルに登録しておきます。
リスト5 RSSをHTMLに変換するXSLTスタイルシート
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=http://www.w3.org/1999/XSL/Transform
xmlns:wfw="http://wellformedweb.org/CommentAPI/">
<xsl:output method="html" />
<xsl:template match="/">
<html xml:lang="ja" lang="ja">
<xsl:apply-templates select="/rss/channel" />
</html>
</xsl:template>
<xsl:template match="/rss/channel">
<head>
<title>
<xsl:value-of select="title" />
</title>
<meta http-equiv="Content-Style-Type" conent="text/css" />
<style>
<xsl:comment>
.title {
font-size: 1.1em;
font-weight: bold;
}
.description {
font-size: .9em;
margin: 0 0 10px 0;
}
.list {
font-size: .8em;
margin:0 0 0 20px;
}
.list-item {
margin: 0 0 5px 0;
}
.list-item a,
.list-item a:link {
color: blue;
}
.list-item a:active,
.list-item a:hover {
color: red;
}
.list-item a:visited {
color: black;
text-decoration: none;
}
.list-item-date {
font-size: .8em;
}
.list-item-description {
font-size: .9em;
}
</xsl:comment>
</style>
</head>
<div class="content-area">
<div class="title">
<xsl:value-of select="title" />
</div>
<div class="description">
<xsl:value-of select="description" />
</div>
<ul class="list">
<xsl:apply-templates select="item" />
</ul>
</div>
</xsl:template>
<xsl:template match="/rss/channel/item">
<li class="list-item">
<a href="{link}" title="{description}">
<xsl:value-of select="title" />
</a>
<span class="list-item-date">
(
<xsl:value-of select="pubDate" />
)
</span>
<div class="list-item-description">
<xsl:value-of select="description" />
</div>
</li>
</xsl:template>
</xsl:stylesheet>
|
実際にXQueryとXSLTRANSFORM関数を組み合わせると以下のようなSQL/XMLになります。XSLTRANSFORM関数はSQL中で利用しなければいけませんので、XQueryはXMLQUERY関数でSQL中に組み込んで利用します。
リスト6 RSSをマッシュアップしHTMLに変換するSQL/XML
SELECT XSLTRANSFORM(XMLDOCUMENT(XMLQUERY(
'<rss version="2.0">
<channel>
<title>RSSのマッシュアップ</title>
<description>複数のRSSをXQueryを使ってマッシュアップします</description>
{
for $c in db2-fn:xmlcolumn("RSS.DOC")/rss/channel/item
where fn:contains($c/title, ''XML'')
order by $c/pubDate descending
return $c
}
</channel>
</rss>'
)) USING XSLT.DOC AS CLOB(1M))
FROM XSLT,SYSIBM.SYSDUMMY1;
|
リスト4のXQueryをそのまま使っていますが、注意点として“fn:contains($c/title, ''XML'')”のようにシングル・クオーテーション(’)のエスケープが必要な場合には、シングル・クオーテーションを2つ重ねる(’’)必要があります。
図2 HTMLでの表示例
変換結果はHTMLになっていますのでFireFoxなどのブラウザで確認することが出来ます。また、cHTML(Compact HTMl)などに変換する別のXSLTスタイルシートを準備することでさまざまなデバイスに対応した結果セットを返すことも可能になります。
おわりに
この文書では、XQueryを使ってRSSなどのXMLインスタンスを簡単にマッシュアップする方法をご紹介しました。XQueryはXMLを処理するのに非常に向いている言語なので、JAVAやPHPなど通常のプログラミング言語では難しかったXMLの操作や編集を簡単に行うことが可能です。興味のある方は、参考文献に挙げたものにも目を通してください。更に面白い使い方を発見できるかもしれません。
参考文献
著者について  | 
|  | データベース関連製品のテクニカル・サポートを経て、2006年よりDB2の新機能であるXMLデータベースのスペシャリストとして、Web 2.0サービスを行うお客様などに対して、XMLデータベースの素晴らしさを説く日々を送る。2007年より、ソフトウェア・エバンジェリストとして、エンタープライズ・マッシュアップがビジネス・イノベーションの鍵となるという事を、伝え続ける。 |
記事の評価
|