pureXML と JSON に対応したアプリケーションを構築する: 第 1 回 DB2 pureXML による JSON の保管とクエリー

単純な JSON と XML とのマッピングを導入する

Web 2.0 でよく使われているテキスト形式の表記法である JSON (JavaScript Object Notation) は、クライアントとサーバーとの間で情報を交換する際に、オブジェクト (またはデータ構造) をシリアライズしたテキストとして表現するために使用されています。アプリケーションによっては、JSON オブジェクトを保持してセッション間で状態を維持するとメリットがある場合があります。この記事を読んで、単純な JSON と XML とのマッピングを導入することによって DB2 pureXML で JSON の保管、管理、クエリーを可能にする方法を学んでください。

Nuno Job, CoOp: DB2 Technical Enablement Specialist, IBM  

Photo of Nuno JobNuno Job は、University of Minho で修士号を取得し、IBM の研修生として T.J. Watson Research Center の pureXML イネーブルメント・チームに参加した経験を持ちます。興味のある対象としては、オープンソース技術、Linux、セキュリティー、プライバシー、Web および階層型データベースなどがあります。現在彼は IBM Toronto の DB2 Technical Enablement Specialist として、顧客が IBM パートナー・プログラムで認証されるための支援、そして IBM Ruby on Rails アプリケーションの維持管理に携わっています。



Susan Malaika, Senior Technical Staff Member, IBM

Photo of Susan MalaikaSusan Malaika は、IBM Information Management Group (IBM Software Group の一部) のシニア・テクニカル・スタッフです。専門分野は XML、Web、データベースで、Global Grid Forum ではグリッド環境でデータをサポートする標準を開発しました。IBM 製品のソフトウェア・エンジニアとして働くかたわら、インターネット・スペシャリスト、データ・アナリスト、アプリケーション設計者兼開発者としても活躍しています。Web に関する共著作があり、トランザクション処理と XML を取り上げた記事も発表しています。彼女は IBM Academy of Technology の一員でもあります。



Michael Schenker (mschenk@us.ibm.com), IBM DB2 for z/OS Optimizer Software Engineer, IBM

Author Photo: Michael SchenkerMichael Schenker は、ドイツの Leipzig University of Applied Science でコンピューター・サイエンスの修士号を取得しました。IBM に入社してから 7 年を数えます。研修生として非リレーショナル・ラッパーを重点とした DB2 情報統合に携わって以来、数々のデータベース関連の製品に取り組んできました。IBM の正社員となったのは 2003年の終わりです。2006年にはデータベース・ツール組織に加わり、IBM Data Studio Developer の DB2 Web サービス・プロバイダー機能を担当しました。SOA および Web 技術における彼の豊富な専門知識は、この間に培ったものです。最近になって、彼は DB2 for z/OS オプティマイザー・チームの一員となりましたが、DB2 内外の SOA と Web 技術には今でも興味を持っています。



2010年 4月 27日 (初版 2009年 10月 13日)

2010年 4月 27 日 – 著者によりダウンロード・ファイル jsonx.zip が更新された新しいファイルに置き換えられました (「ダウンロード」を参照)。更新内容には以下の変更が含まれます。

文書内にマルチバイト文字が見つかった場合に xml2json() 関数で OutOfMemory 例外が発生しないようにしました。

文書内で CLOB の中にマルチバイト文字が見つかった場合に、xml2json() 関数によってそれ以降の文字が削除されないようにしました。

xml2json() 関数の出力フォーマットを定義するオプションのプロパティー・ファイルをサポートしました。

はじめに

JavaScript は ECMA の ECMAScript 言語仕様で定義されたスクリプト言語であり、当初は Web ページの処理機能を強化するために Netscape Navigator (Web ブラウザー) に実装されました。IETF が RFC 4627 に定義した JSON は、オブジェクトや配列などの JavaScript データ構造を、シリアライズされたテキストとして表すフォーマットです。

よく使われる頭字語

  • Ajax: Asynchronous JavaScript + XML
  • API: Application Programming Interface
  • DBMS: Database Management System
  • DOM: Document Object Model
  • HTTP: HyperText Transfer Protocol
  • IETF: Internet Engineering Task Force
  • RFC: Request For Comments
  • RSS: Really Simple Syndication
  • SAX: Simple API for XML
  • SOA: Service Oriented Architecture
  • W3C: World Wide Web Consortium
  • XHTML: Extensible HyperText Markup Language
  • XML: Extensible Markup Language
  • XSLT: Extensible Stylesheet Language Transformations

疎結合されたクライアントとサーバーとの間でメッセージを交換する表現としては XML (W3C で XML 1.0 仕様に定義) が一般的に使われていますが、同じ効果をもたらすために JSON が使用されることもよくあります。JSON を採用する理由の 1 つは、JSON オブジェクトは JavaScript、Python、Ruby などのスクリプト言語で操作しやすいからです。

データベースに XML を保管して、その XML を照会するという考えが生まれたのは、XML がデータ交換方法として普及してきてからのことです。JSON を操作して交換するという方法も同じく一般的になってきたものの、JSON の保管という点ではまだその限りではありません。しかし、JSON ドキュメント指向のデータベース管理システムは次々と登場し始めています。例えば、Apache CouchDB はそのインターフェースとストレージを介して JSON と密接に連携するデータベースです。

この記事では、XML プロセッサー、XML アプライアンス、XML ストレージ (例えば DB2 pureXML などの XML データベース内で一般的に使用されています)、そして XQuery や XSLT などのその他の XML 技術を利用するために、JSON を XML として交換するという概念を紹介します。JSON を XML として交換できるようにするために、私たちは JSONx という XML フォーマットを導入します。そして、JSON からわかりやすい XML 表記へのマッピングについて解説するとともに、JSONx フォーマットとわかりやすいフォーマットとの違いを説明します。

この記事と記事に付属のダウンロードで説明する手順に従えば、DB2 pureXML のサンプル・データベースをベースとした、クエリーを実行可能な索引付き JSON ストアを構築することができます。この記事は、JSON、Web サービス、そして OpenSocial ガジェットを組み込んだ、JSON ベースの 3 層構造の pureXML アプリケーションを構築する方法を説明する 3 回連載の第 1 回目です。

図 1. Universal Services のアーキテクチャーの概観
ユーザー・インターフェース、JSON Universal Services、そしてデータという 3 層で構成される Universal Services アーキテクチャーの図

Universal Services は単純ながらも、DB2 データベースの pureXML 列に保管された XML データに対して照会や変更を行えるようにするデータベース操作の確固たるセットです。これらのデータベース操作には、Data Web Service メカニズムにより Web サービスとして公開されたデータに対する挿入、更新、削除、照会などが含まれます。pureXML 対応 Universal Services についての詳細は、「参考文献」を参照してください。pureXML 対応 JSON Universal Services もクライアントに対して同じデータベース操作を公開しますが、これらの操作は XML ではなく JSON での操作になります。一方、サーバー・サイドではそのまま XML を処理します。クライアント・アプリケーションは、送受信する JSON がサーバー・サイドで XML に変換されてデータベースに保管されることを認識しません。

この記事ではまた、JSON を XML として表現する際の選択肢も取り上げます。それに続いて、いくつかのシナリオを紹介し、IBM DB2 pureXML をこれらのシナリオにどのように適用できるかについて説明します。サンプル JSONx pureXML データベースは、記事に付属のダウンロード (JSONx バンドル) を使用して作成することができます。JSONx アプリケーションの基礎となるこのダウンロードには、JSON から JSONx への変換およびその逆の変換を行う 2 つの DB2 ユーザー定義関数が含まれています。

JSON

JSON はクライアントとサーバーとの間でのデータ交換に使用する、人間が読解できるテキスト・ベースのフォーマットです。開発者にとって JSON は、それぞれが使用するデータ構造に直接マッピングするデータ交換フォーマットとなります。そのために JSON では主なデータ構造として、数値、文字列、ブール値 (true と false)、配列 (値の順序付きシーケンス)、オブジェクト (キーと値のペアのコレクション)、null を定義しています。

リスト 1 に、顧客について記述する JSON オブジェクトの例を記載します。この customerinfo オブジェクトには、顧客 ID (cid) と顧客の名前を定義する 2 つのオブジェクトがネストされている他、さらに 2 つの構造化オブジェクトも含まれています。この 2 つの構造化オブジェクトは、それぞれ顧客の住所、電話番号を定義します。

リスト 1. JSON での Kathy Smith の顧客情報
{
  "customerinfo" : {
	"cid" : 1000 ,
	"name" : "Kathy Smith" ,
	"addr" : {
	  "country"    : "Canada" ,
	  "street"     : "5 Rosewood" ,
	  "city"       : "Toronto" ,
	  "prov-state" : "Ontario" ,
	  "pcode-zip"  : "M6W 1E6"
	} ,
	"phone" : {
	  "work" : "416-555-1358"
	}
  }
}

典型的な JSON シナリオ

JSON の典型的な使用ケースとして挙げられるのは、Web アプリケーションが Yahoo! の Web サービスなどの API や Twitter API を使用してデータを交換するというものです。このシナリオでは、Web アプリケーションは非同期 JavaScript リクエスト (Ajax) を利用して、API を公開する Web サービスとの間で JSON をやり取りします。

Web サービスが公開する API では、アプリケーションがファイルの交換フォーマットを選択できることも珍しくありません。一般的にサポートされるフォーマットとしては、XML、事前定義された XML 標準 (RSS、Atom など)、JSON が挙げられます。「付録 A」にこれらのフォーマットの例を記載しているので参照してください。

アプリケーションと Web サービスとの間での通信に使用するフォーマットを自由に選択できれば、開発者は開発プロセスをスピードアップすることができます。しかしその一方、複数フォーマットを同時にサポートするインフラストラクチャーをどのように保守すればよいのかが問題となります。以下に、複数のフォーマットを同時にサポートするためのデータ・ストレージの選択肢をいくつか挙げます。

  • ドキュメント中心の JSON データベース (例えば Apache CouchDB など) を使用する
  • リレーショナル・データベースを使用し、リクエストごとに JSON をシュレッドして再構成する
  • XML ネイティブ・ストレージ (JSONx を保管するストレージ) を使用し、JSON を公開および処理するインターフェースを提供する

図 2 に、上記に挙げたそれぞれのデータ・ストレージの選択肢の例を示します。

図 2. JSON を保管するさまざまな方法
JSON を保管する 3 つの方法。JSON データベースに保管する方法、リレーショナル・データベースに保管する方法、JSONx として XML ストレージに保管する方法。

上記のどの手法にしても、それぞれに長所と短所があります。この記事では、その違いについて分析することはしませんが、代わりに特定のアプリケーションにとって pureXML を使用することが最も便利な手法となるシナリオに焦点を当てます。XML が最も適した手法となる理由としては、以下の点が考えられます。

  • インフラストラクチャーの残りの部分では、すでに XML と SOA が使用されている
  • JSONx を処理するように拡張可能な既存の XML アプライアンス (例えば IBM Websphere DataPower) と XML 技術がある

JSON と XML との違い

開発者がデータ交換に XML を使用する場合、大抵は XML DOM または SAX によって XML をナビゲートします。操作するにも、交換するにも同じ JSON データ構造を扱うことができれば、オブジェクトへのアクセスをアプリケーションのホスト・プログラミング言語で宣言するという方法で開発プロセスを単純化することができます。

XML では、自己定義された交換表記を提供することに重点が置かれており、この交換表記にそれ自体を交換可能な厳格なスキーマを関連付けて提供することができます。さらに XML は名前空間や圧縮、デジタル・シグニチャーやセキュリティーなどといった多種多様な機能を提供するだけでなく、XQuery や XSLT などの宣言型言語を C、Java™、そして Ruby プログラミング言語から呼び出して、1 つまたは複数の XML 文書を操作することもできます。

XML に備わっているこのような各種の機能は、JSON にはありません。

JSON を XML で表現する方法

この記事の主な目的は、JSON 文書と同一構造の XML フォーマットを生成する方法、つまり、あらゆる JSON 文書とあらゆる XML 文書を対応させられる汎用マッピングの作成方法を説明することです。

JSON 文書と XML との間での効果的なマッピングを行うためには、この 2 つのフォーマットの違いを十分考慮する必要があります。このセクションではその違いを理解できるように、直観的ではあるものの、同一構造ではない XML と JSON とのマッピングについて見ていきます。表 1 はすべてを網羅しているわけではありませんが、そのようなマッピングの例です。

表 1. JSON とわかりやすい XML とのマッピングの例
パターンJSONXML 説明
1{"foo" : "bar"} <foo> bar </foo>文字列型の値を持つオブジェクト
2{"foo" : true} <foo> <true/> </foo>ブール値型の値 (true) を持つオブジェクト
3{"foo" : { "true" : null }} <foo> <true/> </foo>null 型の値を持つネストされたオブジェクトを値に持つオブジェクト
4{"foo bar!" : true} Error: "foo bar!" is not a valid QNameXML QName としては不正な文字 (スペースや感嘆符など) がキーに含まれているため、ブール値型の値 (true) を持つオブジェクトを変換できません。
5{"foo" : null} <foo/>null 型の値を持つオブジェクト
6{"foo": { "bar" : null}}<foo> <bar/> </foo> null 型のリーフ・ノードを値に持つネストされたオブジェクト
7{"foo": { "bar" : [null, false]}} <foo> <bar> <null/> <false/></bar></foo> 配列を値に持つネストされたオブジェクトを持つオブジェクト

ここに記載したのは、正規の JSONx 名を使用する代わりに、JSON に対するわかりやすいフォーマットとしてアプリケーション固有の要素と属性名を使用したマッピング表記ですが、このマッピングには数多くの欠点があります。例えばパターン 2 とパターン 3 は、構造は異なるものの、同じ XML 文書にシリアライズされるため、生成された XML から同じ JSON 文書を再構成することは不可能です。また、パターン 4 のオブジェクト・キーには XML QName では無効な文字が含まれています。これらの制約を克服するために使える手法はいくつかありますが、同一構造による表記ほどの力は発揮しません。そのような表記の一例が、JSONx です。


JSONx

正規の JSON XML (JSONx) は、JSON と同一構造のフォーマットとして導入されます。そのため、前のセクションで説明したわかりやすい表記に伴う問題は、JSONx には当てはまりません。

リスト 1 で JSON フォーマットで表現した Kathy Smith の顧客情報を、リスト 2 では JSONx フォーマットで表現します。

リスト 2. 正規 JSON XML (JSONx) フォーマットでの Kathy Smith の顧客情報
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
  <json:object name="customerinfo">
	<json:number name="cid">1000</json:number>
	<json:string name="name">Kathy Smith</json:string>
	<json:object name="addr">
	  <json:string name="country">Canada</json:string>
	  <json:string name="street">5 Rosewood</json:string>
	  <json:string name="city">Toronto</json:string>
	  <json:string name="prov-state">Ontario</json:string>
	  <json:string name="pcode-zip">M6W 1E6</json:string>
	</json:object>
	<json:object name="phone">
	  <json:string name="work">416-555-1358</json:string>
	</json:object>
  </json:object>
</json:object>

JSONx は、XML データを扱う一方で JSON をサポートするように拡張する必要があるシステムに適したフォーマットです。ただし、JSONx は JSON から XML に変換するために一様に使用できるソリューションではありません。上記の例では、Kathy Smith の元の情報は、わかりやすいフォーマットでは例えば以下のように指定することができます。

リスト 3. わかりやすい XML フォーマットでの Kathy Smith の顧客情報の例
<customerinfo>
  <cid>1000</cid>
  <name>Kathy Smith</name>
  <addr>
	<country>Canada</country>
	<street>5 Rosewood</street>
	<city>Toronto</city>
	<prov-state>Ontario</prov-state>
	<pcode-zip>M6W 1E6</pcode-zip>
  </addr>
  <phone>
	<work>416-555-1358</work>
  </phone>
</customerinfo>

わかりやすいフォーマットの代わりに JSONx を使用することで、標準を使用する場合に一般に関連してくるコードの再利用、共通ツールの使用、変換、そしてフィルタリングがしやすくなります。それでもまだ XML 技術 (XSLT や XQuery など) を使用して、さらにわかりやすい別のフォーマットで文書を公開するビューを作成したいと思う開発者もいることでしょう。

JSONx では、ソリューションをカスタマイズすることなく、既存の XML インフラストラクチャーを使用して JSON を処理および保管することができます。


JSONx バンドル

このセクションでは、DB2 pureXML 対応の JSONx バンドル (スクリプトとコードのコレクション) について概説し、以下を行う方法を説明します。

  • JSON を JSONx に変換する
  • JSONx を JSON に変換する
  • JSON 文書を JSONx としてインポートする
  • JSONx を保管する
  • パフォーマンス向上のために JSONx に索引を付ける
  • JSONx をリレーショナル・フォーマットで公開する
  • JSONx をわかりやすい XML 表記に変換する
  • XMLQuery を使用して JSONx 文書を結合する (オプションでリレーショナル述部を使用)

JSONx バンドルの内容についての詳細は、バンドルと一緒にパッケージ化されている README ファイルを参照してください。

前提条件

JSONx バンドルをインストールして実行するには、DB2 v9.5 以降がインストールされていることが前提となります。必要な場合には、DB2 Express-C をダウンロードすることもできます。pureXML が組み込まれたこの DB2 の無料版は、フル機能のリレーショナルおよび XML データ・サーバーとなります (ダウンロード・サイトへのリンクについては、「参考文献」セクションを参照)。

このパッケージは他のオペレーティング・システムでも動作しますが、パッケージのテストは Ubuntu Jaunty Jackalope 9.04 および Microsoft Windows XP SP2 で行われています。

表の構造

前のセクションでは、Kathy Smith の顧客情報を JSON と JSONx 両方のフォーマットで紹介しました。表 2 に、この情報が保管される CUSTOMER 表について説明します。

表 2. JSONXMLADMIN.CUSTOMER 表
列名データ型説明
CID INTEGER 顧客 ID
INFOXML 顧客に関する個人情報が保管されるレコード
COMMENTVARCHAR(256)顧客を特定するための短いテキスト

この他、JSONx バンドルには製品用と注文書用の 2 つの表 (PRODUCT 表と PURCHASEORDER 表) もあります。

PRODUCT 表には、DESCRIPTION という名前の XML 列に製品情報が保管されるほか、製品の固有 ID も保管されます。

表 3. JSONXMLADMIN.PRODUCT 表
列名データ型内容
PID INTEGER 製品 ID
DESCRIPTION XML 製品に関する個人情報が保管されるレコード

顧客が 1 つ以上の製品を購入すると、PURCHASEORDER 表にそのトランザクションが記述されます。この表に関して興味深い点は、顧客 のID は元の JSON ファイルではなく、別個のリレーショナル列に保管されることです。JSONx と DB2 pureXML を使用することにより、2 つ (またはそれ以上) の異なる JSON 文書からのデータを結合できるだけでなく、リレーショナル・レコードを JSON 文書に結合することもできます。このような結合を行う具体的な例については、JSONx バンドルに含まれるプロシージャー・コードを参照してください。

表 4. JSONXMLADMIN.PURCHASEORDER 表
列名データ型内容
POID INTEGER 注文書 ID
CUSTID INTEGER 関連する顧客 ID
PORDER XML 注文書に関する情報が保管されるレコード

Java ユーザー定義関数による JSON から JSONx への変換

JSONx バンドルは、DB2 に 2 つの Java ユーザー定義関数 (UDF) を登録します。この 2 つの関数が、JSON から JSONx、またはJSONx から JSON への変換を可能にします。リスト 4 は、JSON を JSONx に変換するユーザー定義関数を呼び出す極めて単純な例です。

リスト 4. Java ユーザー定義関数である JSONTOXML の呼び出し
SELECT JSONXML.JSONTOXML('{"foo": "bar"}') FROM SYSIBM.SYSDUMMY1

リスト 5 に、リスト 4 のSELECT 文による出力を記載します。

リスト 5. リスト 4 の呼び出しによって生成された出力
<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
 <json:string name="foo"> bar </json:string>
</json:object>

JSONx を JSON に変換する場合は、XMLTOJSON ストアード・プロシージャーを呼び出します。リスト 6 の例では、リスト 4 で使用した JSON 文書を JSONx にシリアライズしてから、再び JSON に戻しています。

リスト 6. JSON から JSONx への変換、および JSON への再変換
SELECT JSONXML.XMLTOJSON(JSONXML.JSONTOXML('{"foo": "bar"}')) FROM SYSIBM.SYSDUMMY1

複数の JSONx 文書の結合

DB2 pureXML ならではの特徴の 1 つは、データを結合する際の多彩なオプションです。JSONx を DB2 pureXML に保管するということは、XML 文書を結合する場合とまったく同じように JSON データを結合できるようになることを意味します。リスト 7 に、注文書、POID、顧客名のそれぞれに対し、リレーショナル述部と XML 述部の両方で結合を使用して結果を返す方法を説明します。

リスト 7. リレーショナル述部と XML 述部両方での JSONx の結合
SELECT
  POID, 
  XMLCAST (
	XMLQUERY(
	  ''declare default element namespace "http://www.ibm.com/xmlns/prod/2009/jsonx";
	  data( 
		$INFO/object/object[@name="customerinfo"]/string[@name="name"]/text() )''
	  ) AS VARCHAR(32) 
	) AS CUSTNAME
FROM
  JSONXMLADMIN.PURCHASEORDER , 
  JSONXMLADMIN.CUSTOMER
WHERE
  XMLEXISTS(
	''declare default element namespace "http://www.ibm.com/xmlns/prod/2009/jsonx";
	$INFO/object/object[@name="customerinfo"]/number[@name="cid"][. = $CUSTID]'' 
  )

DB2 9.7

JSONx バンドルは、DB2 9.7 pureXML での最新の追加フィーチャーも明らかにします。XMLTABLE を使用して JSONx 文書でビューを作成すると、DB2 9.7 は適用する XML 索引を選択します。そのため、以前のバージョンよりも遙かに短時間でクエリーを実行できるようになっています。

リスト 8. XMLTable によるリレーショナル・ビューとしての JSON の公開
CREATE VIEW JSONXMLADMIN.RELCUSTOMER(CID, NAME, PHONE) AS 
 SELECT  *
 FROM
  XMLTABLE(
   XMLNAMESPACES (DEFAULT 'http://www.ibm.com/xmlns/prod/2009/jsonx'),
   'db2-fn:xmlcolumn("JSONXMLADMIN.CUSTOMER.INFO")'
    COLUMNS
	  "CID" INTEGER 
	  PATH '/object/object[@name="customerinfo"]/number[@name="cid"]/xs:double(.)' ,
	  "NAME" VARCHAR(32) 
	  PATH '/object/object[@name="customerinfo"]/string[@name="name"]/text()' ,
	  "PHONE" VARCHAR(32)
	  PATH '/object/object[@name="customerinfo"]/object[@name="phone"][1]/*[1]/text()'
	)

さらに、SQL/XML パブリッシュ関数を使用してリレーショナル・データから JSONx を生成することも可能です。

新しいフィーチャーとしては、ユーザー定義関数での XML データ型のサポートもあります。このサポートにより、ユーザー定義関数で XML 文書を操作できるようになりました。DB2 9.7 を使用して JSONx バンドルを実行する場合は、2 つの新しいフィーチャーを使用して出力を生成することができます。つまり、ビューでの索引付けと、XML ユーザー定義関数です。

JSONx バンドルに組み込まれている UDF は、XQuery 更新機能を利用して JSON の特定のサブセットを表現するのに適切なフォーマットに JSONx を変換し、JSONx サンプル・データベースの実行が完了した時点でインポートします。リスト 9 は汎用の変換アルゴリズムを代表するものでも、効率的な変換アルゴリズムを代表するものでもありませんが、一例として、DB2 pureXMLを使用して高度な XML ユーザー定義関数を効率的にプログラミングする方法を示します。

リスト 9. わかりやすい XML の生成に XML UDF を使用する例
CREATE FUNCTION JSONXMLADMIN.JSONXTOFRIENDLY(JSONX XML)
RETURNS XML
BEGIN ATOMIC
  RETURN XMLQUERY('
	declare namespace json="http://www.ibm.com/xmlns/prod/2009/jsonx";
	copy $n := $JSONX
	modify(
	  for $e in $n//json:*
	  where $e/@name
	  return (
		do rename $e as replace($e/@name," ", "_") ,
		do delete $e/@name
	  )
	)
	return document { $n/json:object/* }
  ');
END

リスト 10 に、上記でわかりやすい表記に変換した顧客情報を再び JSONx に変換する方法を示します。

リスト 10. Kathy Smith の顧客情報をわかりやすい表記から JSONx に再変換する例
SELECT
  XMLQUERY('
	declare namespace json="http://www.ibm.com/xmlns/prod/2009/jsonx";
	copy $n := $friendly
	modify(
	  for $e in $n//*
	  let $name := local-name($e)
	  let $type := 
		if ($name = ("addr", "phone", "customerinfo")) then "json:object"
		else if ($name eq "cid") then "json:number"
		else "json:string"
	  return (
		do rename $e as $type,
		do insert attribute name { $name } into $e
	  )
	)
	return document { 
	  <json:object>
		{ $n } 
	  </json:object>
	}
  ' PASSING JSONXMLADMIN.JSONXTOFRIENDLY(INFO) as "friendly")
  FROM
	JSONXMLADMIN.CUSTOMER
  WHERE
	CID = 1000

JSONx バンドルの実行方法

JSONx バンドルをセットアップするには、以下に説明する手順に従います。

  • Windows プラットフォームで使用する場合は、お使いのファイル・システムのリソース・セクションにある jsonx.zip ファイルを抽出するだけで構いません。Linux プラットフォームでは、unzip -a -aa jsonx.zip を実行して jsonx.zip ファイルを解凍してください。こうすることにより、正しい行終端文字が使用されることが確実になります。
  • Windows システムでは、DB2 コマンド行プロセッサー環境が初期化されていることを確認します。Linux ベースのシステムでは、DB2 へのアクセス権を持つユーザーとしてログインしていることを確認してください (db2inst1 がデフォルトの DB2 ユーザーです)。
  • これで、スクリプトを実行する準備ができました。(注: 起動スクリプトが一部の DBMS パラメーターを構成した後、DBMS を停止してから再起動する場合があります。これは、DBMS で jar ストアード・プロシージャーを確実に処理できるようにするためです。このようなスクリプトの動作が心配な場合には、スクリプトを実行する前にその内容を調べてください)。Windows プラットフォームでは、start.bat を実行します。Linux プラットフォームでは start.sh を使用してください。このスクリプトの実行が完了すると、コマンド・プロンプトまたは bash に図 3 のような画面が表示されるはずです。
図 3. JSONx バンドルの出力例
JSONx バンドルの出力例
図 3 のテキスト版
db2instl@nuno-laptop:~/Desktop/jsonxml$ ./start.sh
Running JSONXML sample
  . Starting DB2
  . Checking DB2 version
    . DB2 v9.7 detected
  . Configuring environment
  . Creating indexes
  . Registering UDFs
  . Restarting DB2
  . Importing data
  . Registering administrative procedures
  . Registering stored procedures
  . Creating views
  . Adding DB2 v9.7 functionality
  . Populating output folder
    . Query 1
	. Query 2
	. Query 3
	. Query 4
JSONXML configuration and sample run DONE!
Please refer to logs/06-15-2009-13.53.log for a detailed log file

この時点でセットアップは完了です。出力フォルダーでクエリーの結果を調べてみてください。作成された結果が正しいかどうかを調べるには、output フォルダー内にある出力ファイルを、reference フォルダーに配置された参照出力と比較します。

サンプルが reference フォルダーの参照出力と一致しない場合には、logs ディレクトリー内に置かれたログ・ファイルを調べて、実行が失敗した原因を突き止めます。

付録 A」に、わかりやすい XML および JSONx それぞれのフォーマットで Twitter のつぶやきを記載しているので参照してください。


まとめ

今回の記事では、JSON を XML として DB2 pureXML に保管できるようにする新しいフォーマット、JSONx を紹介し、JSONx と他のわかりやすいフォーマットとの違いについて概説しました。典型的な JSON の使用ケースについて説明した後は、pureXML を使用して JSON を保管することの利点を明らかにしました。そして最後に JSONx ダウロード (JSONx バンドル) をセットアップしたので、pureXML 対応の JSON アプリケーションを構築する基礎は整っています。

連載の今後の 2 回の記事では、JSON Universal Services を使用して (JSONx バンドルに作成されている) JSONx サンプル・データベースを公開する方法、続いて JSON Universal Services をバックエンドとした OpenSocial ガジェットによるプレゼンテーション層の作成に焦点を当てます。

また、Web 開発者が JSONPath を使用して (JSONx として保管された) JSON 文書にアクセスする方法についても、機会があれば検討するつもりです。


謝辞

Brien Muschett 氏、William Palma 氏の御協力に感謝いたします。


付録 A

典型的な JSON シナリオ」で述べたように、Web サービスの多くは、情報をいくつものフォーマットで表示できるようになっています。そのようなフォーマットの例には、Atom や RSS などの業界標準や JSON、そしてわかりやすい XML 表記も挙げられます。Twitter では、ID を基準につぶやきにアクセスできる API を提供しています。この付録では、JSON フォーマットおよびわかりやすい XML フォーマットの 2 つのリクエストを curl を使用して Twitter に送信した場合の結果を記載し、続いてわかりやすい XML を JSONx に変換する方法を記載します。

リスト 11 では curl を使用して、twitter.com に投稿された特定のメッセージ (id が 2311383114 のつぶやき) に関する情報をリクエストしています。つぶやきの情報 (およびそのステータス) を取得するために、リスト 11 のように端末から curl を呼び出すと、該当するつぶやきのステータスが JSON フォーマットで返されます (注: リスト 11リスト 12 での curl の呼び出しは、読みやすいように 2 行に分けて記載しています)。

リスト 11. ID 2311383114 のステータスを JSON フォーマットで取得する場合
purexml@watson.ibm.com:~$ curl 
http://purexmltest:3ce3ac99@twitter.com/statuses/show.xml?id=2311383114

{
    "text": "Hello World!",
    "in_reply_to_user_id": null,
    "user": {
        "following": null,
        "favourites_count": 0,
        "profile_sidebar_fill_color": "e0ff92",
        "description": null,
        "verified": false,
        "utc_offset": null,
        "statuses_count": 1,
        "profile_sidebar_border_color": "87bc44",
        "followers_count": 0,
        "created_at": "Wed Jun 24 14:18:32 +0000 2009",
        "url": null,
        "name": "pureXML TEST",
        "friends_count": 0,
        "profile_text_color": "000000",
        "protected": false,
        "profile_image_url": "http:\/\/s3.amazonaws.com\/twitter_production
		\/profile_images\/280225879\/twitterxml-1_bigger_normal.png",
        "profile_background_image_url": "http:\/\/static.twitter.com
		\/images\/themes\/theme1\/bg.gif",
        "notifications": null,
        "time_zone": null,
        "profile_link_color": "0000ff",
        "screen_name": "purexmltest",
        "profile_background_tile": false,
        "profile_background_color": "9ae4e8",
        "location": null,
        "id": 50316451
    },
    "favorited": false,
    "created_at": "Wed Jun 24 15:04:13 +0000 2009",
    "in_reply_to_screen_name": null,
    "truncated": false,
    "id": 2311383114,
    "in_reply_to_status_id": null,
    "source": "web"
}

あるいは、これと同じ文書を Atom、RSS、またはわかりやすい XML 表記で取得することもできます。リスト 12 では、同じ関数を呼び出してステータスを取得していますが、この場合、ステータスはわかりやすい XML 表記で返されます。

リスト 12. ID 2311383114 のステータスをわかりやすい XML フォーマットで取得する場合
purexml@watson.ibm.com:~$ curl 
http://purexmltest:3ce3ac99@twitter.com/statuses/show.xml?id=2311383114

<?xml version="1.0" encoding="UTF-8"?>
<status>
  <created_at>Wed Jun 24 15:04:13 +0000 2009</created_at>
  <id>2311383114</id>
  <text>Hello World!</text>
  <source>web</source>
  <truncated>false</truncated>
  <in_reply_to_status_id></in_reply_to_status_id>
  <in_reply_to_user_id></in_reply_to_user_id>
  <favorited>false</favorited>
  <in_reply_to_screen_name></in_reply_to_screen_name>
  <user>
    <id>50316451</id>
    <name>pureXML TEST</name>
    <screen_name>purexmltest</screen_name>
    <location></location>
    <description></description>
    <profile_image_url>http://s3.amazonaws.com/twitter_production/
	profile_images/280225879/twitterxml-1_bigger_normal.png</profile_image_url>
    <url></url>
    <protected>false</protected>
    <followers_count>0</followers_count>
    <profile_background_color>9ae4e8</profile_background_color>
    <profile_text_color>000000</profile_text_color>
    <profile_link_color>0000ff</profile_link_color>
    <profile_sidebar_fill_color>e0ff92</profile_sidebar_fill_color>
    <profile_sidebar_border_color>87bc44</profile_sidebar_border_color>
    <friends_count>0</friends_count>
    <created_at>Wed Jun 24 14:18:32 +0000 2009</created_at>
    <favourites_count>0</favourites_count>
    <utc_offset></utc_offset>
    <time_zone></time_zone>
    <profile_background_image_url>
http://static.twitter.com/images/themes/theme1/bg.gif</profile_background_image_url>
    <profile_background_tile>false</profile_background_tile>
    <statuses_count>1</statuses_count>
    <notifications></notifications>
    <verified>false</verified>
    <following></following>
  </user>
</status>

リスト 13 に、リスト 12 で取得した結果で DB2 UDF を呼び出して、JSON を JSONx に変換する例を記載します。

リスト 13. リスト 12 で取得した JSON 文書の JSONx 表現
db2 => SELECT JSONXML.JSONTOXML('{"text":"Hello World!",
"in_reply_to_user_id":null,"user":{"following":null,
"favourites_count":0,"profile_sidebar_fill_color":"e0ff92",
"description":null,"verified":false,"utc_offset":null,
"statuses_count":1,"profile_sidebar_border_color":"87bc44",
"followers_count":0,"created_at":"Wed Jun 24 14:18:32 +0000 2009",
"url":null,"name":"pureXML TEST","friends_count":0,
"profile_text_color":"000000","protected":false,"profile_image_url":
"http:\/\/s3.amazonaws.com\/twitter_production
\/profile_images\/280225879\/twitterxml-1_bigger_normal.png",
"profile_background_image_url":"http:\/\/static.twitter.com
\/images\/themes\/theme1\/bg.gif",
"notifications":null,"time_zone":null,"profile_link_color":"0000ff",
"screen_name":"purexmltest","profile_background_tile":false,
"profile_background_color":"9ae4e8","location":null,"id":50316451},
"favorited":false,"created_at":"Wed Jun 24 15:04:13 +0000 2009",
"in_reply_to_screen_name":null,"truncated":false,"id":2311383114,
"in_reply_to_status_id":null,"source":"web"}') FROM SYSIBM.SYSDUMMY1

<json:object xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx">
  <json:string name="text">Hello World!</json:string>
  <json:null name="in_reply_to_user_id"/>
  <json:object name="user">
    <json:null name="following"/>
    <json:number name="favourites_count">0</json:number>
    <json:string name="profile_sidebar_fill_color">e0ff92</json:string>
    <json:null name="description"/>
    <json:boolean name="verified">false</json:boolean>
    <json:null name="utc_offset"/>
    <json:number name="statuses_count">1</json:number>
    <json:string name="profile_sidebar_border_color">87bc44</json:string>
    <json:number name="followers_count">0</json:number>
    <json:string name="created_at">Wed Jun 24 14:18:32 +0000 2009</json:string>
    <json:null name="url"/>
    <json:string name="name">pureXML TEST</json:string>
    <json:number name="friends_count">0</json:number>
    <json:string name="profile_text_color">000000</json:string>
    <json:boolean name="protected">false</json:boolean>
    <json:string name="profile_image_url"
	>http://s3.amazonaws.com/twitter_production/profile_images
	/280225879/twitterxml-1_bigger_normal.png</json:string>
    <json:string name="profile_background_image_url"
	>http://static.twitter.com/images/themes/theme1/bg.gif</json:string>
    <json:null name="notifications"/>
    <json:null name="time_zone"/>
    <json:string name="profile_link_color">0000ff</json:string>
    <json:string name="screen_name">purexmltest</json:string>
    <json:boolean name="profile_background_tile">false</json:boolean>
    <json:string name="profile_background_color">9ae4e8</json:string>
    <json:null name="location"/>
    <json:number name="id">50316451</json:number>
  </json:object>
  <json:boolean name="favorited">false</json:boolean>
  <json:string name="created_at">Wed Jun 24 15:04:13 +0000 2009</json:string>
  <json:null name="in_reply_to_screen_name"/>
  <json:boolean name="truncated">false</json:boolean>
  <json:number name="id">2311383114</json:number>
  <json:null name="in_reply_to_status_id"/>
  <json:string name="source">web</json:string>
</json:object>

ダウンロード

内容ファイル名サイズ
JSONx Bundlejsonx.zip145KB

参考文献

学ぶために

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

  • DB2 Express-C: DB2 データ・サーバーの無料コミュニティー・エディションをダウンロードしてください。
  • IBM 製品の評価版: DB2、Lotus、Rational、Tivoli、および WebSphere のアプリケーション開発ツールとミドルウェア製品を体験するには、評価版をダウンロードするか、IBM SOA Sandbox のオンライン試用版を試してみてください。

議論するために

コメント

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, Information Management, Web development
ArticleID=445366
ArticleTitle=pureXML と JSON に対応したアプリケーションを構築する: 第 1 回 DB2 pureXML による JSON の保管とクエリー
publish-date=04272010