目次


XQuery による更新機能

医療、ビジネス、金融、IT といった業界での DB2 pureXML の使用事例

Comments

はじめに

XML は各種業界で、メッセージ交換フォーマットとして盛んに使われるようになってきています。多くの場合、業界のコンソーシアムや政府では交換メッセージの構造を定義しますが、XML 交換メッセージの使用を促すイニシアチブは増加の一途をたどっています。これらのイニシアチブには、例えば SaaS (Information as a Service and Software as a Service) の他、Web サービス、FTP (File Transfer Protocol)、メッセージング、E メール、Web ベースのフィード情報といった主要な技術も含まれます。

組織は XML 交換メッセージを使用し、生成するなかで、メッセージを (監査のためなどに) 直接保管し始めるようにもなっています。一部のシステムでは、直接保管されたメッセージが公共機関や企業のビジネスをサポートする最新情報の主要なソースになっています。

場合によっては、保管された XML メッセージを変更したり、保管された既存のメッセージから新しいメッセージを派生させたりすることが望ましいこともあります。以下に挙げるのは、更新した XML メッセージを生成する場合の例です。

  • XML メッセージを既存の情報に関連付ける (「リンク」させる) 場合。例えば医療の場合、追加のテスト結果が生成されることがあります。その場合、患者の既存のレコードを基に新しいレコードを作成し、その新規レコードに最近の診断結果を追加します。
  • XML メッセージに追加情報を組み込む場合。例えばビジネスの場合、注文書に後からアイテムを追加することがあります。この手順は大抵の場合、元の注文をキャンセルし、元の注文アイテムと追加の注文アイテムの両方を盛り込んだ新しい注文書を生成するというものです。
  • XML メッセージに変更された情報を組み込む場合。例えば金融デリバティブの処理では、ノベーション (訳注: 既存取引を転売、譲渡などにより第三者に移転すること。欧米市場で活発に行われている。) と呼ばれるプロセスにより、特定の時点で既存の取引相手が新しい取引相手に替わることがあります。

XML 文書の照会に使用できる言語、XQuery には、XML 文書でサブ文書を更新できるようにする拡張機能が追加されています。これらの拡張機能により、新しいノードの追加、既存のノードの削除や名前変更、そして既存のノードやノードの値の置換が可能になっています (XQuery についての詳細は、「参考文献」を参照してください)。

この記事では、W3C 標準の 1 つである XQuery Update Facility を DB2 に保管された XML に適用する方法を説明し、さらに医療、ビジネス、金融デリバティブ、そして IT という 4 つの業界でのコンテキスで XQuery Update Facility の例を紹介します。記事に記載するサンプル・コードは、これらの業界で一般的に使用されているメッセージ交換フォーマットをベースとしています。この記事は以前に書かれた記事、「DB2 9.5 で XML を更新する」(developerWorks、2007年10月) を補完するものです。前回の記事では XQuery による更新機能の基礎について説明し、この機能を利用すると、アプリケーションで XML を読み取り、構文解析して変更するよりも簡単かつ効率的に XML を変更できることをサンプル・データで実演しました。

Industry Bundles をダウンロードして XQuery による更新機能を試してみてください。Industry Bundles は無料で、「Industry Formats and Services with pureXM」という名前の DB2 pureXML オンライン・デモの一部として一般公開されています (「参考文献」を参照)。

XML の変更方法

XML を変更し、場合によっては更新するには、以下を含め、いくつかの方法があります (図 1 を参照)。

  • メモリー内の XML を更新: XML は変更されますが、その変更内容は永続的には保管されません。
  • ディスク上の XML を変更し、変更した XML を同じ場所に保管: 元の XML をベースとした変更バージョンの XML が作成されます。保管されるのは元の XML ではなく変更された XML なので、変更後の XML が元の XML に置き換わります。
  • ディスク上の XML を変更し、変更された XML の新しいバージョンを保管: 元の XML をベースとした変更バージョンの XML が作成されます。変更後の XML は、元の XMLとは別に保管されます。
図 1. XML を変更し、場合によっては更新するさまざまな方法
XML を変更し、場合によっては更新するさまざまな方法
XML を変更し、場合によっては更新するさまざまな方法

XQuery による更新機能を利用した XML 変更の使用パターン

XQuery による更新のサポートを利用して XML で更新を実行する際には、XML の変更方法が更新パターンの基礎となります。更新パターンには、以下の種類があります (図 2 を参照)。

  • XML を保管場所で更新する ((1) update XML stored in-place)
  • XML の変更バージョンを挿入する ((2) insert new version of stored XML)
  • XML リクエストからオンザイフライ (メモリー内) で XML を更新し、XML レスポンスを生成する ((3) retrieve and update XML “on-the-fly” (in memory)))
  • XQuery による更新機能を利用したビューにより XML の内容を部分的に隠す ((4) hide parts of XML)
図 2. XQuery による更新のパターン
XQuery による更新のパターン
XQuery による更新のパターン

XML を保管場所で更新するという方法と、更新バージョンの XML を挿入するという方法の 2 つが、変更後の XML を存続させる主要な方法となります。オンザフライで XML を更新する場合、XML リクエストもレスポンスもデータベースに保管されませんが、そのうちの一方または両方を保管することも可能です。XQuery による更新機能を利用したビューによって XML の内容を部分的に隠すという方法では、保管された内容は変更されないものの、従来のリレーショナル・ビューが持つセキュリティー機能を利用することができます。

以降のパラグラフで、それぞれのパターンについて詳しく説明するとともに、サンプル・コードを記載します。これらのサンプルでは、DB2 pureXML データベース内に XML 型の列を 1 列含む、複数の列からなるテーブルがあることを前提としています。

XML を保管場所で更新する

XML を保管場所で更新するということは、XQuery の UPDATE 表記に従って、元の XML でサブ文書を更新することを意味します。

リスト 1 に示す SQL/XML 文には、元の XML 内の zip コードを変更し、元の XML を変更後の XML に置き換える XQuery UPDATE 文が組み込まれています。

リスト 1. 元の XML を更新済み XML に置き換える場合の XQuery による更新
UPDATE xmlcustomer
   SET info = XMLQUERY('transform 
                        copy      $new := $i
                        modify    do replace value of $new/customerinfo/addr/zipcode 
                                                   with 90111
                        return    $new' PASSING info AS "i")
 WHERE cid = 1000;

XML の変更バージョンを挿入する

既存の XML を更新する一方、元の XML も維持するためのもう 1 つの方法は、既存の XML とは別に、更新後の完全な新しいレコードを挿入することです。

リスト 2 に示す SQL/XML 文には、新しい行を挿入する XQuery 文が組み込まれています。この新しい行に、元の XML をベースに変更された XML が含まれます。

リスト 2. 変更バージョンの XML をデータベースに挿入する場合の XQuery による更新
INSERT INTO xmlcustomer (cid, 
                         info) 
     VALUES (1003, 
             XMLQUERY('transform
                       copy      $new := $i
                       modify    do replace value of $new/customerinfo/addr/zipcode
                                                  with 90111
                       return    $new' PASSING (SELECT info
                                                FROM   xmlcustomer
                                                WHERE  cid=1000) as "i"));

XML リクエストからオンザイフライで XML を更新し、XML レスポンスを生成する

XML をオンザフライで更新するということは、つまり、XML 変数または列から取得したメモリー内の XML を変更するということです。

リスト 3 に示す XQuery 文は、XML 内の zip コードを取得してオンザフライで変更します。

リスト 3. メモリー内に XML の変更バージョン生成する場合の XQuery による更新
XQUERY 
for    $doc in db2-fn:sqlquery('SELECT info
                                FROM   xmlcustomer
                                WHERE  cid=1000')
return transform 
       copy      $new := $doc
       modify    do replace value of $new/customerinfo/addr/zipcode 
                                  with 90111
       return    $new;

XQuery による更新機能を利用したビューにより XML の内容を部分的に隠す

場合によっては、特定のユーザーに対して XML を部分的に隠したり、曖昧にしたりする必要があります。例えば、医療スタッフに社会保障番号 (訳注: 社会保障番号は、米国社会保障局が米国の住民に対して発行している、個人を特定できる番号) が見えないようにしたり、あるいは調査のために顧客の機密情報を削除したりするなどの場合です。XML では、XQuery による更新機能を利用して XML を部分的に隠したり、再編成したりしたビューを作成することができます。ただし、XQuery による更新機能を利用したビューによってアクセスする場合、そのパフォーマンスを慎重に確認する必要があることに注意してください。

リスト 4 に、XML にアクセスするソフトウェアに対し、anonymousCust ビューによって顧客の名前、住所、zip コード、電話番号を隠す方法を示します。

リスト 4. XML を部分的に隠したビューの作成で使われている XQuery による更新
CREATE VIEW anonymousCust (custInfo) 
    AS SELECT XMLQUERY('for    $ci in $i 
                        return transform   
                               copy      $c := $i 
                               modify    (do delete $c/customerinfo/name,
                                          do delete $c/customerinfo/addr/street, 
                                          do delete $c/customerinfo/addr/zipcode, 
                                          do delete $c/customerinfo/phone) 
                               return    $c' PASSING info AS "i") 
         FROM xmlcustomer;

HL7 による更新 (バージョン管理およびチェーニング)

HL7 (Health Level 7) は、医療情報交換分野における標準開発機構 (Standards Developing Organization (SDO)) です。HL7 が仕様を策定する上で基礎とする情報モデルは RIM (Reference Information Model: 参照情報モデル) で、HL7 の仕様はすべてこのモデルから派生しています。これらの仕様の 1 つに、医療文書を交換する目的でその構造とセマンティクスについて記述した CDA (Clinical Document Architecture) があります。CDA 文書には、患者の名前、住所、性別といった情報や、投薬治療に関する情報などを含めることができます。

CDA 文書に含まれる構造とセマンティクスの他、この仕様では既存の CDA 文書の更新方法についても定義しています。以下は、CDA 文書を更新する場合の一例です。

Megan Brown という患者が、血液検査のために近くの開業医を訪れました。検査当日、Megan は開業医に自分の住所の詳細を伝えませんでしたが、血液検査が終わってから数日後に住所の詳細を送りました。

上記の例の場合、CDA 文書を更新して Megan の住所が含まれるようにする必要があります。それには、CDA 文書自体を更新するという方法が考えられますが、CDA 仕様では既存の CDA 文書を直接更新してはならないと規定しています。直接更新する代わりに、元の文書のコピーを作成し、そのコピーに必要な更新を加えるという方法を採らなければなりません。CDA 文書のコピーを更新するだけでなく、更新後の文書には既存の元の CDA 文書への参照を追加する必要があります (CDA についての詳細は、「参考文献」を参照してください)。

図 3 に、仕様に従った CDA 文書の更新方法を示します。

図 3. CDA 文書の更新シナリオ
CDA 文書の更新シナリオ
CDA 文書の更新シナリオ

それぞれの CDA 文書には、その文書に固有の ID を割り当てる <id> 要素があります。CDA 文書のバージョン管理は、<setId> 要素と <versionNumber> 要素によって行われます。元の文書とその更新バージョンは同じ <setId> を持ちますが、<versionNumber> はそれぞれに異なります。この場合、<setId> は両方の文書が 1 つのグループであることを示し、<versionNumber> がそのバージョンを示します。さらにバージョン管理情報の他に、文書間のいわゆる「関係」も定義しなければなりません。元の文書が更新バージョンに置き換えられる例の場合は、当該文書が別の文書によって置き換わるという関係を定義する必要があります。このような関係を定義するために使用されるのは、<relatedDocument> 要素です。

コード・スニペット

リスト 5 に、CDA 文書からの抜粋を記載します。この文書には患者の情報が含まれますが、重要な連絡先情報は欠けています。

リスト 5. 元の HL7 CDA サンプル XML 文書からの抜粋
...
<id root="2.16.840.1.113883.3.18.1" extension="2"/>
<setId root="2.16.840.1.113883.3.18.1" extension="2"/>
<versionNumber value="1" />
...
<patient>
  <name>
    <family>Megan</family>
    <given>Brown</given>
  </name>
  <administrativeGenderCode 
     code="F" 
     codeSystem="2.16.840.1.113883.5.1" />
  <birthTime value="198110070000" />
  <birthplace>
    <place>
      <addr>
        <city>San Jose</city>
        <country>United States of America</country>
        <postalCode>95102</postalCode>
      </addr>
    </place> 
  </birthplace>
</patient>
...

図 2 に示した例によると、この CDA 文書は患者の住所情報を補う必要があります。リスト 6 の CDA 文書の抜粋には、患者の住所情報が追加されています。さらに、この抜粋には必要なバージョン管理情報も記載されています。

リスト 6. 更新後の HL7 CDA サンプル XML 文書からの抜粋
...
<id root="2.16.840.1.113883.3.18.1" extension="2-1"/>
<setId root="2.16.840.1.113883.3.18.1" extension="2"/>
<versionNumber value= "2" />
...
<addr>
  <streetName>Martine Ave</streetName>
  <houseNumber>11</houseNumber>
  <houseNumberNumeric>11</houseNumberNumeric>
  <city>San Jose</city>
  <postalCode>95102</postalCode>
  <country>United States of America</country>
</addr>

<patient>
  <name>
    <family>Megan</family>
    <given>Brown</given>
  </name>
  <administrativeGenderCode 
     code="F" 
     codeSystem="2.16.840.1.113883.5.1" />
  <birthTime value="198110070000" />
...
</patient>
...
<relatedDocument typeCode="RPLC">
  <parentDocument>
    <id root="2.16.840.1.113883.3.18.1" 
        extension="2" />
  </parentDocument>
</relatedDocument>
...

CDA 文書を更新すると同時に、元の CDA 文書を維持して正しいバージョン管理情報を追加するには、リスト 7 に記載する SQL/XML 文を使用します。

リスト 7. SQL/XML 文による CDA 文書の更新
INSERT INTO BUCKET (id, document) 
VALUES (11,
        XMLQUERY('declare default element namespace "urn:hl7-org:v3"; 
        for     $doc in $p 
        let     $newAddress := <addr>
                                 <streetName>Martine Ave</streetName>
                                 <houseNumber>11</houseNumber>
                                 <houseNumberNumeric>11</houseNumberNumeric>
                                 <city>San Jose</city>
                                 <postalCode>95102</postalCode>
                                 <country>United States of America</country>
                               </addr> 
        let     $IdRoot := $doc/ClinicalDocument/id/@root 
        let     $IdExtension := $doc/ClinicalDocument/id/@extension 
        let     $relationship := <relatedDocument typeCode="RPLC">
                                   <parentDocument>
                                     <id root="{$IdRoot}" 
                                         extension="{$IdExtension}" />
                                   </parentDocument>
                                 </relatedDocument> 
        return  transform 
                copy      $c := $doc 
                modify   (do insert $newAddress 
                             after $c/ClinicalDocument/recordTarget/patientRole/id,
                          do replace 
                             value of $c/ClinicalDocument/versionNumber/@value 
                             with xs:integer($c/ClinicalDocument/versionNumber/@value)+1,
                          do replace 
                             value of $c/ClinicalDocument/id/@extension 
                             with fn:concat($c/ClinicalDocument/id/@extension, "-1"), 
                          do insert $relationship 
                             after $c/ClinicalDocument/recordTarget)
                return    $c' PASSING (SELECT document 
                                         FROM bucket 
                                        WHERE id=1) as "p")
        )@

UBL による購入注文 (バージョン管理)

UBL (Universal Business Language) (「参考文献」を参照) は、OASIS (Organization for the Advancement of Structured Information Standards) 技術委員会が開発した言語で、その開発目標は、購入注文書や請求書などの標準電子 XML ビジネス文書のロイヤリティー・フリーのライブラリーを定義することでした。OASIS 技術委員会の定義によると、UBL は、「ビジネス、法律、監査、記録管理の既存のプラクティスに直接結び付き、既存のファックスまたは紙ベースのサプライ・チェーンにデータを再入力することなく、e-コマースや中小企業へのエントリー・ポイントを提供するように設計」されています。

なかでも UBL のバージョン 2.0 には、以下の単純なサンプル・シナリオで使用する「Order」文書および「OrderChange」文書のための XML スキーマが含まれています。このシナリオでは、一方のビジネス・パートナー (買い手) がもう一方のビジネス・パートナー (売り手) に注文を送信します。売り手はこの注文に対し、「OrderResponse」文書を送信することで確認応答します。注文へのレスポンスを受け取った買い手は、程なく元の注文書に記入された配送先住所が誤っていることに気付きます。この場合、買い手がこのエラーを訂正する方法はいくつかあります。

  1. 「OrderChange」文書を送信する (方法その 1、図 4 を参照)
  2. 元の注文をキャンセルして新しい注文を送信する (方法その 2、図 5 を参照)
  3. 帯域外通信を使用する (例えば、売り手に直接電話をかけるなど)

リスト 8 は、誤った配送先住所が指定された元の Order XML 文書からの抜粋です。

リスト 8. 誤った配送先住所が指定された UBL Order XML 文書からの抜粋
<Order ...
...
<cbc:UUID>6E09886B-DC6E-439F-82D1-7CCAC7F4E3B1</cbc:UUID>
<cbc:IssueDate>2007-10-15</cbc:IssueDate>
<cac:BuyerCustomerParty>...</cac:BuyerCustomerParty>
<cac:SellerSupplierParty>...</cac:SellerSupplierParty>
...
<cac:Delivery>
  <cac:DeliveryAddress>
    <cbc:StreetName>Avon Way</cbc:StreetName>
    <cbc:BuildingName>Thereabouts</cbc:BuildingName>
    <cbc:BuildingNumber>56A</cbc:BuildingNumber>
    <cbc:CityName>Bridgetown</cbc:CityName>
    <cbc:PostalZone>ZZ99 1ZZ</cbc:PostalZone>
    <cac:Country>
      <cbc:IdentificationCode>GB</cbc:IdentificationCode>
    </cac:Country>
  </cac:DeliveryAddress>
  <cac:RequestedDeliveryPeriod>
    ...
  </cac:RequestedDeliveryPeriod>
</cac:Delivery>
...
<cac:OrderLine>
  <cac:LineItem>...</cac:LineItem>
  ...
</cac:OrderLine>
...
</Order>

方法その 1. 買い手が誤りを訂正するための OrderChange 文書を送信する

図 4. 方法その 1 による既存の購入注文の訂正
方法その 1 による既存の購入注文の訂正
方法その 1 による既存の購入注文の訂正

買い手が XQuery 式 (リスト 10 に記載) を使用して、既存の Order 文書 (リスト 8 に記載) から OrderChange 文書 (リスト 9 に記載) を生成します。

リスト 9. 正しい配送先住所が設定された UBL OrderChange 文書からの抜粋
<OrderChange ...
...
<cbc:UUID>6E09886B-DC6E-439F-82D1-8BCFC7A4ECCC</cbc:UUID>
<cbc:IssueDate>2007-10-16</cbc:IssueDate>
<cbc:SequenceNumberID>1</cbc:SequenceNumberID>
<cac:BuyerCustomerParty>...</cac:BuyerCustomerParty>
<cac:SellerSupplierParty>...</cac:SellerSupplierParty>
...
<cac:Delivery>
  <cac:DeliveryAddress>
    <cbc:StreetName>Stratford Way</cbc:StreetName>
    <cbc:BuildingNumber>111</cbc:BuildingNumber>
    <cbc:CityName>Bridgetown</cbc:CityName>
    <cbc:PostalZone>ZZ99 1ZZ</cbc:PostalZone>
    <cac:Country>
      <cbc:IdentificationCode>GB</cbc:IdentificationCode>
    </cac:Country>
  </cac:DeliveryAddress>
  <cac:RequestedDeliveryPeriod>
  ...
  </cac:RequestedDeliveryPeriod>
</cac:Delivery>
...
<cac:OrderLine>
  <cac:LineItem>...</cac:LineItem>
  ...
</cac:OrderLine>
...
</OrderChange>
リスト 10. UBL Order XML 文書 (リスト 8) から UBL OrderChange XML文書 (リスト 9) を生成する XQuery 式
XQUERY 
declare default element namespace 
  "urn:oasis:names:specification:ubl:schema:xsd:Order-2"; 
declare namespace cac = 
  "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
declare namespace cbc = 
  "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";

for     $doc in db2-fn:sqlquery('select data from ubladmin.ubltable where id=100') 
let     $SequenceNumber := <cbc:SequenceNumberID>1</cbc:SequenceNumberID> 
let     $newAddress := <cac:DeliveryAddress>
                         <cbc:StreetName>Stratford Way</cbc:StreetName>
                         <cbc:BuildingNumber>111</cbc:BuildingNumber>
                         <cbc:CityName>Bridgetown</cbc:CityName>
                         <cbc:PostalZone>ZZ99 1ZZ</cbc:PostalZone>
                         <cac:Country>
                           <cbc:IdentificationCode>GB</cbc:IdentificationCode>
                         </cac:Country>
                       </cac:DeliveryAddress>
return  transform 
        copy      $c := $doc 
        modify    (do rename $c/Order 
                      as "OrderChange",
   		       do replace 
                      value of $c/Order/cbc:UUID 
                      with "6E09886B-DC6E-439F-82D1-8BCFC7A4ECCC",
                   do replace 
                      value of $c/Order/cbc:IssueDate 
                      with "2007-10-16",
                   do insert $SequenceNumber 
                      after $c/Order/cbc:IssueDate,
                   do replace $c/Order/cac:Delivery/cac:DeliveryAddress 
                      with $newAddress)
         return    $c

OrderChange 文書を生成したら、買い手はその文書を売り手に送信します。OrderChange 文書を生成する際は、Order 文書と異なるところを OrderChange 文書用にするために、XQuery 式は以下の処理をする必要があります。

  • <Order> 要素を「OrderChange」に名前変更する
  • UUID 要素と IssueDate 要素の値を新しい値に置き換える
  • 新しい SequenceNumber を挿入する
  • 既存の <cac:DeliveryAddress> 要素を新しく作成したものと置き換える

<cac:DeliveryAddress> 要素を完全に置き換える代わりに、誤ったサブ要素のみを置き換えることもできます (リスト 11 を参照)。

リスト 11. UBL Order XML 文書 (リスト 8) から新しい UBL Order XML 文書 (リスト 12) を生成する XQuery 式
XQUERY 
declare default element namespace 
  "urn:oasis:names:specification:ubl:schema:xsd:Order-2"; 
declare namespace cac = 
  "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2";
declare namespace cbc = 
  "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2";

for    $doc in db2-fn:sqlquery('select data from ubladmin.ubltable where id=100') 
return transform 
       copy      $c := $doc 
       modify   (do replace
                    value of $c/Order/cbc:UUID 
                    with "6E09886B-DC6E-439F-82D1-8BCFC7A4ECCC",
                 do replace 
                    value of $c/Order/cbc:IssueDate 
                    with "2007-10-16",
                 do replace 
                    value of $c/Order/cac:Delivery/cac:DeliveryAddress/cbc:StreetName 
                    with "Stratford Way",
                 do replace value of 
                    $c/Order/cac:Delivery/cac:DeliveryAddress/cbc:BuildingNumber 
                    with "111",
                 do delete 
                    $c/Order/cac:Delivery/cac:DeliveryAddress/cbc:BuildingName)
       return    $c

方法その 2. 買い手が既存の注文をキャンセルし、エラーを訂正した新しい Order 文書を送信する

図 5. 方法その 2 による既存の購入注文の訂正
方法その 2 による既存の購入注文の訂正
方法その 2 による既存の購入注文の訂正

買い手がリスト 11 のような XQuery 式を使用して、既存の Order 文書 (リスト 8) から新しい Order 文書を生成し、それを売り手にサブミットするという方法もあります。

リスト 12. 正しい住所を指定した新しい UBL Order XML 文書からの抜粋
<Order ...
...
<cbc:UUID>6E09886B-DC6E-439F-82D1-8BCFC7A4ECCC</cbc:UUID>
<cbc:IssueDate>2007-10-16</cbc:IssueDate>
<cac:BuyerCustomerParty>...</cac:BuyerCustomerParty>
<cac:SellerSupplierParty>...</cac:SellerSupplierParty>
...
<cac:Delivery>
  <cac:DeliveryAddress>
    <cbc:StreetName>Stratford Way</cbc:StreetName>
    <cbc:BuildingNumber>111</cbc:BuildingNumber>
    <cbc:CityName>Bridgetown</cbc:CityName>
    <cbc:PostalZone>ZZ99 1ZZ</cbc:PostalZone>
    <cac:Country>
      <cbc:IdentificationCode>GB</cbc:IdentificationCode>
    </cac:Country>
  </cac:DeliveryAddress>
  <cac:RequestedDeliveryPeriod>
  ...
  </cac:RequestedDeliveryPeriod>
</cac:Delivery>
...
<cac:OrderLine>
  <cac:LineItem>...</cac:LineItem>
  ...
</cac:OrderLine>
...
</Order>

新しい Order 文書を作成するには、XQuery 式が UUID 要素と IssueDate 要素の値を新しい値に置き換えるだけでなく、<cbc:StreetName> 要素と <cbc:BuildingNumber> 要素の既存の値も正しい値に置き換え、<cbc:BuildingName> 要素を削除する必要があります。

FpML デリバティブ (ノベーションのリクエストとレスポンス)

FpML (Financial products Markup Language) は、ISDA (International Swaps and Derivatives Association) が定義した XML 表記で、非公式に交渉されたデリバティブ (契約) を記述します。FpML の作成に際して、ISDA は OTC (Over the Counter) デリバティブでのマーケットを構成する投資銀行のコミュニティー代表として活躍しています (ISDA、FpML についての詳細は、「参考文献」を参照してください)。

XML は FpML に最適です。これは、新種のデリバティブが次々に生み出されていることから、XML のような柔軟な表記が必要となるためです。今日、FpML には 600 を超える XML 型、1730 を超える XML 要素、そして 21 を超える XML スキーマ・ファイル (XSD) があるため、リレーショナル・テーブルなどの他の表記では簡単には表現できません。

この記事に記載する FpML での XQuery による更新例 (図 6 を参照) に、ノベーション・リクエスト (「参考文献」を参照) に対してレスポンスを生成する仕組みを示します。ノベーションとは、既存の取引相手を新しい取引相手との契約に置き換えるための同意のことです。

図 6. FpML ノベーション
FpML ノベーション
FpML ノベーション

コード・スニペット

リスト 13 に、ノベーション・リクエストを記載します。

リスト 13. ノベーション・リクエストからの抜粋
<FpML version="4-2"
   xmlns=http://www.fpml.org/2005/FpML-4-2
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xsi:schemaLocation="http://www.fpml.org/2005/FpML-4-2  
                       ../../fpml-main-4-2.xsd
                       http://www.w3.org/2000/09/xmldsig#  
                                   xmldsig-core-schema.xsd" 
  xsi:type="NovationConsentRequest">
  ...
  <novation>
    <oldTransaction>
      <partyTradeIdentifier>
        <partyReference href="abcBank"/>
          <tradeId tradeIdScheme=
                   "http://www.abcbank.com/tradeId/OTC">
             TradeABC0001
          </tradeId>
      </partyTradeIdentifier>
    </oldTransaction>
    <newTransactionReference>
      <partyTradeIdentifier>
        <partyReference href="xyzBank"/>
          <tradeId tradeIdScheme=
                  "http://www.xyzbank.com/tradeId/OTC">
            TradeXYZ0001
          </tradeId>
      </partyTradeIdentifier>
      </newTransactionReference>

リスト 14 は、期待されるノベーション・レスポンスです。

リスト 14. ノベーション・レスポンスからの抜粋
<FpML version="4-2"
   xmlns=http://www.fpml.org/2005/FpML-4-2
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
   xsi:schemaLocation="http://www.fpml.org/2005/FpML-4-2  
                       ../../fpml-main-4-2.xsd
                       http://www.w3.org/2000/09/xmldsig#  
                                   xmldsig-core-schema.xsd" 
  xsi:type="NovationConsentGranted">
  ...
  <novation>
    <oldTransactionReference>
      <partyTradeIdentifier>
        <partyReference href="abcBank"/>
          <tradeId tradeIdScheme=
                   "http://www.abcbank.com/tradeId/OTC">
             TradeABC0001
          </tradeId>
      </partyTradeIdentifier>
    </oldTransactionReference>
    <newTransactionReference>
      <partyTradeIdentifier>
        <partyReference href="xyzBank"/>
          <tradeId tradeIdScheme=
                  "http://www.xyzbank.com/tradeId/OTC">
            TradeXYZ0001
          </tradeId>
      </partyTradeIdentifier>
    </newTransactionReference>

リスト 15 に、XQuery による更新機能を使用してノベーション・レスポンスまたは確認を生成する方法を説明します。

リスト 15. SQL/XML 文による FpML ノベーション確認の生成
INSERT INTO BUCKET (id, document) 
VALUES (33,
        XMLQUERY('declare default element namespace "http://www.fpml.org/2005/FpML-4-2";
                  declare namespace xsi = "http://www.w3.org/2001/XMLSchema-instance"; 
                  for     $doc in $f 
                  let     $reference := $doc/FpML/novation/oldTransaction/tradeHeader
                                            /partyTradeIdentifier[last()] 
                  let     $oldReference := <oldTransactionReference>
                                             {$reference}
                                           </oldTransactionReference> 
                  return  transform 
                          copy      $c := $doc 
                          modify    (do replace 
                                        value of $c/FpML/@xsi:type 
                                        with "NovationConsentGranted", 
                                     do insert $oldReference 
                                        before $c/FpML/novation/newTransactionReference,
                                     do delete $c/FpML/novation/oldTransaction) 
                          return    $c' PASSING (SELECT document 
                                                   FROM bucket 
                                                  WHERE id=3) as "f")
                )@

Web 2.0 APP — Atom Store 用 API (メモリー内での更新)

Atom では以下の 2 つの関連標準を規定しています (詳細は、「参考文献」を参照)。

  • Atom 配信フォーマット (Atom Syndication Format) は、Web フィードのレイアウトを記述する XML 表記です。フィードには多数のエントリーがあり、特定のカテゴリー (例えば、中国のスポーツなど) に属する最近のニュース項目のリストを Atom フィードで表現した場合、それぞれのニュース項目が Atom エントリーによって表されることになります。
  • Atom 出版プロトコル (Atom Publishing Protocol (APP)) は、Atom フォーマットの Web リソースを作成、更新するための HTTP プロトコルです。APP は、多くのリソースが Atom による表現を使うように促進することを目的としています。

Atom 表記で保管された XML のデータ・コレクションは、Atom Store と呼ばれます。

図 7. Atom のシナリオ
Atom のシナリオ
Atom のシナリオ

Atom にも XML が最適な理由は、ヒューマン・ユーザー・インターフェースをはじめとする多種多様なツールと技術が Atom フィードをサポート、交換、保管する必要があるからです (図 7 を参照)。

この記事の XQuery による Atom の更新例では、Atom フィードのエントリーを変更する方法を説明します。リスト 16 に、フィードのエントリーを記載します。

リスト 16. Atom エントリー
<entry xmlns="http://www.w3.org/2005/Atom">
  <author>
         <name>Lonely John</name>
  </author>
  <title>Scary Nights</title>
  <content type="xhtml" xml:lang="en-US">
    <div xmlns="http://www.w3.org/1999/xhtml">
       It was a dark and stormy night
    </div>
  </content>
  <published>
    2006-07-13T10:59:26-07:00
  </published>
</entry>

リスト 17 には、エントリーを変更し、複数のリンクを追加した後のエントリーを記載します。

リスト 17. 更新後の Atom エントリー
<entry xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>John the brave</name>
    <email>johnb@ibm.com</email>
  </author>
  <id xmlns="http://www.w3.org/2005/Atom">b8b2332285095249</id>
  <summary xmlns="http://www.w3.org/2005/Atom" type="xhtml">
   <div xmlns="http://www.w3.org/1999/xhtml">
      <a href="http://atomfeeds.com?col=97">
        <img src="//atomfeeds.com?col=97" 
             alt="Media of type application"/>
      </a>
    </div>
  </summary>
  <created xmlns="http://www.w3.org/2005/Atom" 
           by="johnb@ibm.com">2007-09-26T21:15:10.541636Z
  </created>
  <updated xmlns="http://www.w3.org/2005/Atom" 
           by="johnb@ibm.com">2007-09-26T21:15:10.541636Z
  </updated>
  <link xmlns="http://www.w3.org/2005/Atom" rel="self"
        href="http://atomfeeds.com?col=97"/>
  <link xmlns="http://www.w3.org/2005/Atom" rel="edit" 
         href="http://atomfeeds.com?col=97"/>
  <link xmlns="http://www.w3.org/2005/Atom" rel="edit-media" 
        href="http://atomfeeds.com?col=97&media"/>
  <title>Media of type application</title>
  <content xmlns="http://www.w3.org/2005/Atom" 
           type="application/x-www-form-urlencoded" 
           src="//atomfeeds.com?col=97"/>
</entry>

リスト 18 では、XQuery による更新を使用して、APP のいくつかの側面を実装し、変更された Atom フィード・エントリーを生成する方法を示しています。

リスト 18. 元のエントリーから変更された Atom フィード・エントリーを生成する XQuery による更新
XQUERY declare default element namespace 'http://www.w3.org/2005/Atom'; 
  for $doc in db2-fn:sqlquery('select document from bucket where id=2') 
  let $newTitle := "Media of type application" 
  let $newAuthor := <author>
                      <name>John the brave</name>
                      <email>johnb@ibm.com</email>
                    </author> 
  let $newId := <id>b8b2332285095249</id> 
  let $summary := <summary type="xhtml"> 
                    <div xmlns="http://www.w3.org/1999/xhtml"> 
                      <a href="http://atomfeeds.com?col=97"> 
                      <img src="//atomfeeds.com?col=97" 
                           alt="Media of type application"/></a> 
                    </div> 
                  </summary> 
  let $newContent := <content type="application/x-www-form-urlencoded" 
                              src="//atomfeeds.com?col=97"/> 
  let $created := <created by="johnb@ibm.com">2007-09-26T21:15:10.541636Z</created> 
  let $updated := <updated by="johnb@ibm.com">2007-09-26T21:15:10.541636Z</updated> 
  let $linkSelf := <link rel="self" href="http://atomfeeds.com?col=97"/> 
  let $linkEdit := <link rel="edit" href="http://atomfeeds.com?col=97"/> 
  let $linkEditMedia := <link rel="edit-media" href="http://atomfeeds.com?col=97&media"/> 
  return transform copy $c := $doc 
         modify (do delete $c/entry/published, 
                 do replace value of $c/entry/title with $newTitle, 
                 do replace $c/entry/author with $newAuthor, 
                 do replace $c/entry/content with $newContent, 
                 do insert $newId after $c/entry/author, 
                 do insert $summary after $c/entry/author, 
                 do insert $created after $c/entry/author, 
                 do insert $updated after $c/entry/author, 
                 do insert $linkSelf after $c/entry/author, 
                 do insert $linkEdit after $c/entry/author, 
                 do insert $linkEditMedia after $c/entry/author) 
         return $c@

ガイドライン

XML をデータベースに保管し、変更リクエストを処理する際の一般的な設計ストラテジーは、保管されている元の XML は変更せずに、変更を加えた新しいバージョンの XML を作成することです。この新しい変更バージョンには、タイムスタンプを付けたり、バージョン番号を付与したり、あるいはこの 2 つを組み合わせたりすることで、変更が行われた日、変更が適用されるタイミングを示します。業界でのメッセージ・フォーマットのなかには、明示的なバージョン管理によって、変更されたデータをどのように扱えばよいかを説明しているものもあります。医療業界が、その一例です。

ある種のバージョン管理やタイムスタンプを取り込んだ設計手法は、外部世界での出来事を厳密に映し出し、コンピューター・システムでの処理を実際の規約とプラクティスに関連付けやすくします。バージョン管理とタイムスタンプはまた、コンプライアンスの扱いも容易にします。

まとめ

この記事では、XQuery による更新機能を利用してメモリー内あるいは DB2 pureXML データベースに保管された XML を変更する方法を、4 つの業界、医療、ビジネス、金融デリバティブ、そして IT でのコンテキストで説明しました。

特にお金がからんでくる場合をはじめ、現実の世界では情報を直接変更することはめったになく、一般には変更履歴を維持することが適切なプラクティスとなっています。そのため、XML メッセージ、そして保管されている既存の XML メッセージの新しいバージョンを保管することが、ガバナンスおよびコンプライアンスのイニシアチブのサポートに役立ちます。

この記事では、XQuery による更新機能を利用することによって、上記のガイドラインに従って保管された XML の新しいバージョンを作成する方法、あるいは監査が必要ない場合や別のシステムが監査を行う場合に XML を保管場所で置換する方法を説明しました。さらに、XQuery による更新機能を利用して XML リクエスト・メッセージから派生した XML レスポンス・メッセージを生成する例、そしてビューを使用して情報を隠す例も紹介しました。


ダウンロード可能なリソース


関連トピック

  • Industry Formats and Services with pureXML: 多彩に揃ったサンプルを無料でダウンロードしてください。それぞれのサンプルによって XML ベースの Industry Formats と pureXML を操作する方法がわかります。XML スキーマの登録方法、XML インスタンス文書の検証方法、XQuery または SQL/XML を使用した XML データのクエリー方法を紹介するサンプルもあります。
  • W3C の XQuery Update Specification: XQuery (XML Query Language) Update Facility の仕様を調べてください。
  • DB2 9.5 で XML を更新する」(developerWorks、2007年10月): XML に永続的変更を加えることができる DB2 pureXML の新機能、XQuery Update Facility について紹介しています。さらに、この記事には DB2 pureXML での XQuery Update Facility をわかりやすく説明するサンプルも記載されています。
  • Wikipedia の HL7 についての記事: SDO (Standards Developing Organization) のHealth Level 7 (HL7) について概説しています。
  • HL7: SDO (Standards Developing Organizatio) HL7 (Health Level 7) のメインページでは、この標準および関連リソース (リンク、コンファレンスの詳細、仕様など) を紹介しています。
  • Wikipedia の UBL についての記事: UBL (Universal Business Language) について概説しています。
  • UBL: OASIS (Organization for the Advancement of Structured Information Standard) で、UBL (Universal Business Language) 技術委員会についての詳細を調べてください。
  • Wikipedia の FpML についての記事: FpML (Financial product Markup Language) について概説しています。
  • FpML: FpML (Financial products Markup Language) のメインページに、さまざまなリソース (ツールや資料など) が揃っています。
  • Wikipedia の Atom についての記事: Atom Syndication Format と Atom Publishing Protocol について概説しています。
  • Atom Publishing Protocol: IETF の RFC5023 が Atom Publishing Protocol を規定しています。
  • HL7 (Health Level 7) CDA (Clinical Document Architecture): CDA (Clinical Document Architecture) の元の仕様です。
  • developerWorks Information Management ゾーン: 情報管理について詳しく学んでください。このゾーンには、技術文書やハウツー記事、教育資料、ダウンロード、製品情報その他が豊富に用意されています。
  • DB2 Express-C:pureXML 技術など、他の Data Servers と同じ機能が組み込まれた DB2 の無料バージョンをダウンロードしてください。pureXML 技術をはじめ、他の Data Servers と同じ機能が組み込まれた DB2 Express-C は自由に開発、デプロイ、配布できます。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Information Management, XML
ArticleID=349939
ArticleTitle=XQuery による更新機能
publish-date=10092008