V7R1 XML サポートの基本 (チュートリアルの紹介)

DB2 for IBM i V7R1 から、データベースに XML 型のカラムを定義することができるようになっています。

XML 型のカラムと言っても実際には CLOB だったり BLOB だったりするわけですが、その内容を XML として処理するための関数もあわせて用意されています。
この XML 処理関数と XML カラムのサポートの双方を V7R1 の「XML サポート」というわけです。

この「XML サポート」の基本的な内容を理解するための XML チュートリアル というものがインフォメーション・センターに載っています。

本当のベースとなる基本機能のとっても簡潔な紹介になっていますので、今回はこれを一通りやってみた結果を紹介してみたいと思います。


準備

まず、テーブル等を格納するためのスキーマの作成です。

CREATE SCHEMA POSAMPLE;

System i ナビゲータ「SQL スクリプトの実行」機能を使用して今後の SQL を実行していきます。

↑で作成したスキーマをデフォルトに設定するために↓のように SET CURRENT SCHEMA 文を実行しておきます。

SET CURRENT SCHEMA POSAMPLE;

XML カラムの定義

XML 型のカラムを持ったテーブルを作成します。

CREATE TABLE Customer 
             (Cid BIGINT NOT NULL PRIMARY KEY, 
              Info XML);

DSPFFD コマンドで内容を見てみましょう。
「データタイプ」が XML になっていますね。

ちなみに CCSID が 1208 になっているのは、QAQQINISQL_XML_DATA_CCSID 値のデフォルトが 1208 になっているからなんですね。

XML データの挿入

XML データを XML カラムに挿入します。

一番単純なのは XML データをそのまま '(クォーテーション)で囲んで指定する方法ですね。

INSERT INTO Customer (Cid, Info) 
VALUES (1000, 
        '<customerinfo xmlns="http://posample.org" Cid="1000"> 
          <name>Kathy Smith</name> 
          <addr country="Canada"> 
            <street>5 Rosewood</street> 
            <city>Toronto</city> 
            <prov-state>Ontario</prov-state> 
            <pcode-zip>M6W 1E6</pcode-zip> 
          </addr> 
          <phone type="work">416-555-1358</phone> 
        </customerinfo>');

続けて 2件挿入しておきます。

INSERT INTO Customer (Cid, Info) 
VALUES (1002, 
       '<customerinfo xmlns="http://posample.org" Cid="1002"> 
         <name>Jim Noodle</name> 
         <addr country="Canada"> 
           <street>25 EastCreek</street> 
           <city>Markham</city> 
           <prov-state>Ontario</prov-state> 
           <pcode-zip>N9C 3T6</pcode-zip> 
         </addr> 
         <phone type="work">905-555-7258</phone> 
       </customerinfo>');

INSERT INTO Customer (Cid, Info) 
VALUES (1003, 
       '<customerinfo xmlns="http://posample.org" Cid="1003"> 
         <name>Robert Shoemaker</name> 
         <addr country="Canada"> 
           <street>1596 Baseline</street> 
           <city>Aurora</city> 
           <prov-state>Ontario</prov-state> 
           <pcode-zip>N8X 7F8</pcode-zip> 
         </addr> 
         <phone type="work">905-555-2937</phone> 
       </customerinfo>');

SELECT * FROM CUSTOMER で、データ挿入の結果を確認してみましょう。

XML カラムの更新

XML データの更新を行ってみましょう。

UPDATE 文の SET 句で、XML データをまるごと指定します。

UPDATE customer 
   SET info = 
       '<customerinfo xmlns="http://posample.org" Cid="1002"> 
         <name>Jim Noodle</name> 
         <addr country="Canada"> 
           <street>1150 Maple Drive</street> 
           <city>Newtown</city> 
           <prov-state>Ontario</prov-state> 
           <pcode-zip>Z9Z 2P2</pcode-zip> 
         </addr> 
         <phone type="work">905-555-7258</phone> 
       </customerinfo>' 
WHERE Cid = 1002;

SELECT 文で確認してみましょう。

CID が 1002 の行で、XML データの<street> のところのデータが変わっているのがわかりますね。

XML スキーマを使っての XML ファイルの妥当性検査

ここまでは XML データを XML カラムに入力するごく単純な形を見てきました。

XML データは、XML スキーマというものを使用して、その形式の妥当性を検査することができます。
必要項目がすべて存在するか、おかしな書き方はしていないか等を、データ受け取り時(ここでは XML カラムへの挿入時)に確認することができるわけですね。

妥当性検査を行うための XML スキーマは XML Schema Repository (XSR) というところに格納する必要があります。

XML スキーマの XSR への登録

妥当性検査は XMLVALIDATE という組み込み関数で実行されます。
具体的に言うと、XMLVALIDATE (対象の XML データ) ACCORDING TO XML SCHEMA ID xxx という構文で検査される際の xxx で参照できるように、XSR に事前に登録しておく必要がある、ということです。

登録にはいくつかのシステム提供ストアド・プロシージャを使用します。

カンタンに言うと、SYSPROC.XSR_REGISTER で登録し、必要なら SYSPROC.XSR_ADDSCHEMADOC で追加し、SYSPROC.XSR_COMPLETE で登録を完了する、といった流れになります。

ストアド・プロシージャの引数に XML スキーマを指定するようになっているわけですが、XML スキーマにはけっこう長い、大きなものもありますので、↓のように登録用のストアド・プロシージャを作って対応するというのも一案です。
一旦、XML スキーマを変数として定義して、その変数を登録用のストアド・プロシージャの引数にその変数を指定するわけです。

CREATE PROCEDURE SAMPLE_REGISTER
LANGUAGE SQL
BEGIN
  DECLARE CONTENT BLOB(1M);
  VALUES BLOB
('<?xml version="1.0"?>
  <xs:schema targetNamespace="http://posample.org"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:element name="customerinfo">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="name" type="xs:string" minOccurs="1" />
          <xs:element name="addr" minOccurs="1" maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="street" type="xs:string" minOccurs="1" />
                <xs:element name="city" type="xs:string" minOccurs="1" />
                <xs:element name="prov-state" type="xs:string" minOccurs="1" />
                <xs:element name="pcode-zip" type="xs:string" minOccurs="1" />
              </xs:sequence>
              <xs:attribute name="country" type="xs:string" />
            </xs:complexType>
          </xs:element>
          <xs:element name="phone" nillable="true" minOccurs="0" maxOccurs="unbounded">
            <xs:complexType>
              <xs:simpleContent>
                <xs:extension base="xs:string">
                  <xs:attribute name="type" form="unqualified" type="xs:string" />
                </xs:extension>
              </xs:simpleContent>
            </xs:complexType>
          </xs:element>
          <xs:element name="assistant" minOccurs="0" maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="name" type="xs:string" minOccurs="0" />
                <xs:element name="phone" nillable="true" minOccurs="0" maxOccurs="unbounded">
                  <xs:complexType>
                    <xs:simpleContent  >
                      <xs:extension base="xs:string">
                        <xs:attribute name="type" type="xs:string" />
                      </xs:extension>
                    </xs:simpleContent>
                  </xs:complexType>
                </xs:element>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
        <xs:attribute name="Cid" type="xs:integer" />
      </xs:complexType>
    </xs:element>
  </xs:schema>')
  INTO CONTENT;

  CALL SYSPROC.XSR_REGISTER('POSAMPLE', 'CUSTOMER', 'http://posample.org', CONTENT, null);

END;

↑のストアド・プロシージャを実行し、XML スキーマを登録します。

SET PATH POSAMPLE;

CALL SAMPLE_REGISTER;

XSR_COMPLETE ストアド・プロシージャを実行して XML スキーマの登録を完了させます。
以後、この XML スキーマは POSAMPLE スキーマの CUSTOMER という ID で参照できるようになります。

CALL SYSPROC.XSR_COMPLETE('POSAMPLE', 'CUSTOMER', null, 0);

XSR については、↓のように System i ナビゲータから内容を見ることもできます。

↓のように XSROBJECTS システム・テーブルから内容を参照することもできます。

XML スキーマを使用した XML データの妥当性検査しながらの挿入

妥当性検査をしながらの XML データの挿入は、↓のように XMLVALIDATE 〜 ACCORDING TO XML SCHEMA ID 組み込み関数で行います。

INSERT INTO Customer(Cid, Info) 
VALUES (1004, 
        XMLVALIDATE (XMLPARSE (DOCUMENT 
           '<customerinfo xmlns="http://posample.org" Cid="1004"> 
             <name>Robert Shoemaker</name> 
             <addr country="Canada"> 
               <street>1596 Baseline</street> 
               <city>Aurora</city> 
               <prov-state>Ontario</prov-state> 
               <pcode-zip>N8X 7F8</pcode-zip> 
             </addr> 
             <phone type="work">905-555-7258</phone> 
             <phone type="home">416-555-2937</phone> 
             <phone type="cell">905-555-8743</phone> 
             <phone type="cottage">613-555-3278</phone> 
           </customerinfo>' PRESERVE WHITESPACE )
        ACCORDING TO XMLSCHEMA ID posample.customer ));

CID が 1004 のデータが新しく挿入されていることがわかりますね。

XSLT スタイルシートを使用した XML データの他フォーマットへの変換

演習 5: XSLT スタイルシートを使用した変換」はいろいろあって結局うまくいきませんでした。。

CREATE TABLE XML_TAB (DOCID INTEGER, XML_DOC XML, XSL_DOC CLOB(1M));

INSERT INTO XML_TAB VALUES
     (1,
      '<?xml version="1.0"?>
      <students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <student studentID="1" firstName="Steffen" lastName="Siegmund" 
          age="23" university="Rostock"/>
      </students>',

     '<?xml version="1.0"encoding="UTF-8"?>
     <xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:param name="headline"/>
     <xsl:param name="showUniversity"/>
     <xsl:template match="students">    
         <html>
         <head/>
         <body>
         <h1><xsl:value-of select="$headline"/></h1>
         <table border="1">
         <th>
         <tr>
         <td width="80">StudentID</td>
         <td width="200">First Name</td>
         <td width="200">Last Name</td>
         <td width="50">Age</td>
         <xsl:choose>
              <xsl:when test="$showUniversity =''true''">
                   <td width="200">University</td>
              </xsl:when>
         </xsl:choose>
         </tr>
         </th>
         <xsl:apply-templates/>
         </table>
         </body>
         </html>
         </xsl:template>
              <xsl:template match="student">
                   <tr>
                   <td><xsl:value-of select="@studentID"/></td>
                   <td><xsl:value-of select="@firstName"/></td>
                   <td><xsl:value-of select="@lastName"/></td>
                   <td><xsl:value-of select="@age"/></td>
                   <xsl:choose>
                        <xsl:when test="$showUniversity = ''true'' ">
                             <td><xsl:value-of select="@university"/></td>
                        </xsl:when>
                   </xsl:choose>
                   </tr>
          </xsl:template>
     </xsl:stylesheet>'
);

まず、↑の XSLT スタイルシートの XML カラムへの挿入ですが、これが QZDASOINIT のジョブ CCSID を 37 に変更しないと、エラーが出て完了できませんでした。

CCSID を変更してやっと XSLT スタイルシートを格納できたと思ったら、今度は実際の変換ができません … 導入しているライセンスが足りなくてできないようです。。

SELECT XSLTRANSFORM (XML_DOC USING XSL_DOC AS CLOB(1M)) 
 FROM XML_TAB;

XSLT スタイルシートを使用した XML データの他フォーマットへの変換: その後

その後、ちょっと試行錯誤してみました。

XML データの変更による対応

まず、挿入する XML データを変更すると、ジョブの CCSID を 37 に変更しなくても INSERT が成功することがわかりました。

XML_DOC に挿入する XML データを

INSERT INTO XML_TAB VALUES
     (1,
      '<?xml version="1.0"?>
      <students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <student studentID="1" firstName="Steffen" lastName="Siegmund" 
          age="23" university="Rostock"/>
      </students>',

から

INSERT INTO XML_TAB VALUES
     (1,
      <students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <student studentID="1" firstName="Steffen" lastName="Siegmund" 
          age="23" university="Rostock"/>
      </students>',

にしてみたところ、INSERT できるようになりました。(つまり <?xml version="1.0"?> を削除したわけです)

CCSID を 37 に変更せずに(一応は)データを挿入できたので、気をよくしてそのまま XSLTRANSFORM をやってみると …

そもそもその機能に行くまでに問題があるらしく、エラーで実行できません。
CCSID を 37 に変更してやり直してみると、以前と同じエラーになります。

データタイプの定義の変更による対応

また、XML データをそのままでも、テーブルのデータタイプを変更することで INSERT できる方法も見つけました。

XML_DOC のデータタイプを XML 型から CCSID 1208 を指定した CLOB に変更することで対応できます。
<?xml version="1.0"?> はそのままです。

こちらのケースでも XSLTRANSFORM 機能については同じエラーになります …

[Top Pageに戻る]

Ads by TOK2