データベースのデータをXML文書に変換するには?
データベースからデータを取得した後、それをXML形式に変換したいと考えています。具体的な方法を教えてください。

回答/富士ソフトABC株式会社 技術センター
2001/9/14

 データベースの内容をXMLに変換する機能は、最近のデータベースでは標準的な機能として提供されているものもあります。ここでは参考例として、XML形式のデータを使ったデータベースへのアクセスについて、その方法を説明します。

 利用する環境として、Windows 2000上でマイクロソフトのSQL Server 2000を想定します。また、データベースのスキーマとして、下記を想定します。

Personテーブル
番号 ID
名前 Name
住所 Address
電話番号 Phon

 この環境下で、あるデータベース(データベースA)から、データをXML形式で取り出してファイルに保存します。その逆に、保存されたXML形式のファイルからデータを取り出して、別のデータベース(データベースB)に登録する方法も考えます。

 つまり、データベースからデータを取り出す処理と、データベースにデータを登録する処理の2つについて考えていきます。

■データベースからXML形式で取り出す

 まずデータベースからデータをXML形式で取り出す方法ですが、SQL Server 2000では以下のSQL文が利用できます。

SELECT * FROM テーブル名 FOR XML AUTO (,ELEMENTS)

 SELECT文ですべての情報を対象とし、テーブル名の後ろに「FOR XML」句を付加することでデータをXML形式で取り出すことができます。「FOR XML」句の後ろの「AUTO」は、XMLモードの指定で、「AUTO」を指定すると結果をネストされたXML要素として返します。XMLモードにはこのほかに「RAW」と「EXPLICIT」の2つのモードがあります。最後の「ELEMENTS」はオプションで、これを指定すると列がすべて子要素として返されます。

 下の例は、ELEMENTSオプションを指定しない場合(例1)と、指定した場合(例2)の結果です。

(例1)
<Person id="1" Name="鈴木" Address="東京都" Phon="03-xxxx-aaaa">
<Person id="2" Name="佐藤" Address="北海道" Phon="012-345-6789">
<Person id="3" Name="富士" Address="京都府" Phon="0yz-mmm-tttt">

(例2)
<Person><id>1</id><Name>鈴木</Name><Address>東京都</Address><Phon>03-xxxx-aaaa</Phon></Person>
<Person><id>2</id><Name>佐藤</Name><Address>北海道</Address><Phon>012-345-6789</Phon></Person>
<Person><id>3</id><Name>富士</Name><Address>京都府</Address><Phon>0yz-mmm-tttt</Phon></Person>

 取り出したデータをファイルに保存すれば、データベースからデータをXML形式で取り出す処理は完了します。

 保存するときに注意しなければならない点が1つあります。SQL Serverから取得したデータには、ルート要素がないことです。データのみを取得するため、XML宣言もありません。正しいXML文書として保存するためには、例えば下記のように、SQL Server 2000から取得したデータにXML宣言とルート要素を追加する必要があります。

[リスト1]
<?xml version="1.0" encoding="Shift_JIS"?>
<root>
<Person><id>1</id><Name>鈴木</Name><Address>東京都</Address><Phon>03-xxxx-aaaa</Phon></Person>
<Person><id>2</id><Name>佐藤</Name><Address>北海道</Address><Phon>012-345-6789</Phon></Person>
<Person><id>3</id><Name>富士</Name><Address>京都府</Address><Phon>0yz-mmm-tttt</Phon></Person>
</root>

 SQL Server 2000に保存されているデータをXML形式で取得してファイルに保存する方法についてJavaでコーディングした場合のプログラムを、リスト1(GetXMLData.java)に示しておきます。

■XML形式のデータをデータベースに入れる

 次にXML形式でファイルに保存されているデータを、データベースに登録する方法について説明しましょう。

 最初に大きな問題を解決する必要があります。XML文書を読み込むデータベースのスキーマ(テーブルの構造)を、どのように決定するかです。先ほど説明した、データベースの内容をXML文書として保存したファイルには、元のデータベースのスキーマ情報は含まれていません。もちろん、一般的なXML文書も、そのような情報(データベースのスキーマ)を持つことはありません。

 そのため、XML文書を読み込むためのスキーマを定義するには、結局元のデータベースの定義を目で見て調べるなどして作成することになります。また、SQL Server 2000が持っている、XML文書の読み込み機能である「OPENXML」を使う処理には、ストアドプロシージャを記述する必要があります。

 ここでは、まずSQL Server 2000にデータベースを新しく作成し、データを入力するためのテーブルとストアドプロシージャを作成するためのSQLスクリプトを用意します。それをクエリアナライザを使って処理してから、データを入力する方法を紹介します。

 リスト2の例では、「TestDB」というデータベースを作成し、そこに「Person」というテーブルを作成しています。さらに、XML文書をテーブルに入力するためのストアドプロシージャを作成しています。Personテーブルには“ID”(ID)、“Name”(名前)、“Address”(住所)、“Phon”(電話番号)の4つの項目があります。

 ここで紹介しているSQLスクリプトは一気に実行するような形で記述されていますが、データベース作成については、個々の機能ごとに切り離して実行してください。その際には、まずデータベースを作成し、クエリアナライザのデータベースの選択を作成したデータベースに変更してから、残りのスクリプトを実行するようにしてください。

注) SQLスクリプトは一気に実行できますが、エラーが発生する場合もあるので、各部ごとに実行した方が確実に実行できます。

[リスト2] SQL スクリプト
/***** データベース作成 *****/
create database TestDB
GO

/***** データベースの選択をした後に以下のスクリプトを実行する ****/
USE TestDB
GO

/***** テーブル(Person)の新規作成 *****/
CREATE TABLE [dbo].[Person] (
[ID] [int] NOT NULL ,
[Name] [varchar] (50) COLLATE Japanese_CI_AS NULL ,
[Address] [varchar] (50) COLLATE Japanese_CI_AS NULL ,
[Phon] [varchar] (50) COLLATE Japanese_CI_AS NULL
) ON [PRIMARY]
GO

/***** ストアドプロシージャの新規作成 *****/
/***** この処理では XML 形式で記述されたデータをパースしてデータをテーブルに追加します *****/
CREATE PROC InsData
@doc varchar(8000)
AS
DECLARE @idoc int
EXEC sp_xml_preparedocument @idoc OUTPUT, @doc
INSERT INTO Person
SELECT * FROM
OPENXML(@idoc, '/Person', 2)
WITH ([ID] [int] ,
[Name] [varchar] (50) ,
[Address] [varchar] (50) ,
[Phon] [varchar] (20))
EXEC sp_xml_removedocument @idoc
GO

 上記のスクリプトを実行したら、あとはデータを登録する処理を実行するだけです。処理手順としては、登録するデータがXML形式で記述されているファイルを読み込んで、先ほど作成したストアドプロシージャを呼び出すだけです。

 SQL Server 2000からデータをXML形式で取り出した場合、取り出したデータはテーブル名を親にして各カラムが子の形式の構造になっています。取り出しでは、そのデータにルート要素とXML宣言を付加して保存しました。このデータを登録する場合、ファイル内のデータすべてを1回の処理で登録できません。

 これは、SQL Server 2000ではテーブル名をルート要素、各カラムを子要素とした形式の構造を登録の単位としているためで、この登録単位のデータを複数同時に与えるとSQL Server 2000はデータを正しく処理できずにエラーになってしまいます。そのため、登録処理は登録単位の個数回繰り返す必要があります。登録するデータにはXML宣言を付加した方がいいでしょう。特にエンコードの指定がないと、2バイトコードのデータが正確に解析されずに登録されたデータが正しくなかったり登録エラーになったりすることがあります。リスト3(SetXMLData.java)は、データを登録する処理をJavaでコーディングした場合のプログラムです。

注1) データを登録する際XML宣言を付加せずに行うと、登録したデータのうち特に2バイトコードが正しく登録されない現象に悩まされました。今回はSQL Server 2000での確認しかしていないためすべての状況で当てはまるとはいえませんが、XML形式のデータを扱うデータベースでは登録するXMLデータのエンコードについて注意してください。

注2) 取得したデータを加工したり、すでにあるXMLデータファイルを使用したりする場合、XMLデータのファイル内での記述方法が一般的な記述(例3)ではSQL Server側でエラーとなってしまうため、1レコードの情報を1行で記述(例4)する必要があります。取得した情報には改行は入りません。

(例3)
<Person>
<id>1</id>
<Name>鈴木</Name>
<Address>東京都</Address>
<Phon>03-xxxx-aaaa</Phon>
</Person>

(例4)
<Person><id>1</id><Name>鈴木</Name><Address>東京都</Address><Phon>03-xxxx-aaaa</Phon></Person>

 

「Ask XML Expert」


XML & SOA フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

HTML5+UX 記事ランキング

本日月間