Forum und email

SDO XML データアクセスサービス関数

導入

SDO 用の XML データアクセスサービスを使用するには、 SDO の背景となる概念を理解しておく必要があります。例えば データグラフ、データオブジェクト、XPath とプロパティの表現法などを理解しておきましょう。 これらの概念になじみがない場合は、まず最初に SDO の節を見るとよいでしょう。

XML DAS の役割は、アプリケーションと XML データソースとの間のデータ移動を行うことです。 XML データソースは、ファイルあるいは URL のどちらでも使用可能です。 SDO の作成およびメンテナンスは、常にモデルに基づいて行われます。 型の名前やその型が保持するプロパティの名前などがモデルに定義されています。 XML から取得するデータの場合は、XML スキーマ言語 (xsd ファイル) で記述されたスキーマファイルに基づいて SDO モデルが作成されます。 XMLDAS を初期化する際に、このスキーマファイルが作成メソッドに渡されることが多くなります。 » SDO 2.0 仕様 で、XML と SDO の間での型の対応が定義されています。 PHP の実装では、制限がいくつかあり、 仕様に書かれている内容がすべて実装されているわけではありません。 この制限については後でまとめます。

要件

SDO XML データアクセスサービスには PHP 5.1.0 以降が必要です。 また、SDO 拡張モジュールに同梱されているものであるため、 SDO がインストールされていなければなりません。 インストール方法の詳細については、 SDO のインストール手順 を参照ください。

インストール手順

XML データアクセスサービスは、 SDO 拡張モジュール の一部として提供されており、同時にインストールされます。 SDO のインストール手順 を参照ください。

以下の例のいくつかは、 SDO のドキュメントで説明した letter の例を使用しています。 この例では、litter の XML スキーマが letter.xsd に、そしてインスタンスが letter.xml に保存されていることを想定しています。 これらの 2 つのファイルは次のようになります。

<xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema"
  xmlns:letter="https://letterSchema"
  targetNamespace="https://letterSchema">
  <xsd:element name="letters" type="letter:FormLetter"/>
  <xsd:complexType name="FormLetter" mixed="true">
    <xsd:sequence>
      <xsd:element name="date" minOccurs="0" type="xsd:string"/>
      <xsd:element name="firstName" minOccurs="0" type="xsd:string"/>
      <xsd:element name="lastName" minOccurs="0" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

<letter:letters xmlns:letter="https://letterSchema">
  <date>March 1, 2005</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Casy</firstName>
  <lastName>Crocodile</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</letter:letters>

Example#1 XML ドキュメントの読み込み・変更そして保存

次の例では、XML ドキュメントをファイルから読み込んでその内容を変更し、 もう一度書き戻す方法を示します。

<?php
/**
 * XML ドキュメントの読み込み・更新そして保存
 */
try {
   
$xmldas SDO_DAS_XML::create("letter.xsd");
   
$document $xmldas->loadFile("letter.xml");
   
$root_data_object $document->getRootDataObject();
   
$root_data_object->date "September 03, 2004";
   
$root_data_object->firstName "Anantoju";
   
$root_data_object->lastName "Madhu";
   
$xmldas->saveFile($document"letter-out.xml");
   echo 
"New file has been written:\n";
   print 
file_get_contents("letter-out.xml");
} catch (
SDO_Exception $e) {
   print(
$e->getMessage());
}
?>

まず最初に、SDO_DAS_XML::create() メソッドで XML DAS のインスタンスを取得します。 このメソッドは、SDO_DAS_XML クラスの静的メソッドです。パラメータとして xsd の場所を渡します。 スキーマを指定して XML DAS のインスタンスを初期化したら、 loadFile() メソッドを使用してインスタンスドキュメントを読み込むことができます。 もし文字列から XML インスタンスドキュメントを読み込みたいのなら、 loadString() メソッドを使用することも可能です。 インスタンスドキュメントの読み込みに成功したら SDO_DAS_XML_Document 型のオブジェクトが返されます。 このオブジェクトに対して getRootDataObject() メソッドをコールすると、SDO データグラフのルートとなる SDO データオブジェクトが取得できます。 その後、SDO に対する操作によってグラフを変更します。 この例では datefirstName そして lastName のプロパティを変更しています。 その後で saveFile() メソッドを使用して、 ドキュメントをファイルシステムに書き戻します。 saveFile メソッドにはオプションで整数型の引数を指定することができ、 これが設定されていると、XML DAS が結果の XML の書式を整形します。 指定された整数値のぶんだけ、ドキュメントの字下げが行われます。

この例の結果、以下のような内容が letter-out.xml に書き出されます。

<?xml version="1.0" encoding="UTF-8"?>
<FormLetter xmlns="https://letterSchema" xsi:type="FormLetter" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <date>September 03, 2004</date>
  Mutual of Omaha
  Wild Kingdom, USA
  Dear
  <firstName>Anantoju</firstName>
  <lastName>Madhu</lastName>
  Please buy more shark repellent.
  Your premium is past due.
</FormLetter>

Example#2 新しい XML ドキュメントの作成

さきほどの例ではファイルからドキュメントを読み込みました。 この例では、メモリ上で SDO データグラフを作成する方法を示します。 この例では、データグラフが XML 文字列として保存されます。 さらに、letter の中に構造化されたデータとされていないデータの両方が含まれていることから、 シーケンス API を使用してプロパティを割り当て、データグラフを作成します。

<?php
/**
 * スクラッチからの XML ドキュメントの作成
 */
try {
   
$xmldas SDO_DAS_XML::create("letter.xsd");
   try {
       
$doc $xmldas->createDocument();
       
$rdo $doc->getRootDataObject();
       
$seq $rdo->getSequence();
       
$seq->insert("April 09, 2005"NULL'date');
       
$seq->insert("Acme Inc. "NULLNULL);
       
$seq->insert("United Kingdom. ");
       
$seq->insert("Dear"NULLNULL);
       
$seq->insert("Tarun"NULL"firstName");
       
$seq->insert("Nayaraaa"NULL"lastName");
       
$rdo->lastName "Nayar";
       
$seq->insert("Please note that your order number ");
       
$seq->insert(12345);
       
$seq->insert(" has been dispatched today. Thanks for your business with us.");
       print(
$xmldas->saveString($doc));
   } catch (
SDO_Exception $e) {
       print(
$e);
   }
} catch (
SDO_Exception $e) {
   print(
"Problem creating an XML document: " $e->getMessage());
}
?>

XML DAS の createDocument() メソッドは、空のドキュメント要素に対応するルートデータオブジェクトを ひとつだけ含むドキュメントオブジェクトを返します。 ドキュメント要素の要素名はスキーマファイルから取得します。 ドキュメント要素をはっきり特定できない場合 (例えば同一の XML DAS に対して複数のスキーマを読み込むことも可能です) は、 要素名に加えて名前空間 URI を createDocument() メソッドに渡します。

この例は、次のような内容を出力します (読みやすくするために適宜改行を挿入しています)。

<?xml version="1.0" encoding="UTF-8"?>
<FormLetter xmlns="https://letterSchema" xsi:type="FormLetter"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
<date>April 09, 2005</date>
Acme Inc. United Kingdom.
Dear
<firstName>Tarun</firstName>
<lastName>Nayar</lastName>
Please note that your order number 12345 has been
dispatched today. Thanks for your business with us.
</FormLetter>

Example#3 XML ドキュメントのプロパティの設定

3 番目のこの例では、ドキュメントに対して XML のバージョンとエンコーディングを設定する方法を示します。 これらは、XML を書き出す際に使用されます。 XML 宣言が不要な場合 (XML を文字列として作成してどこかに埋め込むなどの場合がそうでしょう) は、 setXMLDeclaration() メソッドを使用して宣言を抑制することができます。

<?php
/**
 * XML 宣言を制御するためのコール方法
 */
   
$xmldas SDO_DAS_XML::create("letter.xsd");
   
$document $xmldas->loadFile("letter.xml");
   
$document->setXMLVersion("1.1");
   
$document->setEncoding("ISO-8859-1");
   print(
$xmldas->saveString($document));
?>

XML のバージョンおよびエンコーディングは、 XML ドキュメントの先頭にあたる XML 宣言で設定されます。

<?xml version="1.1" encoding="ISO-8859-1"?>
.../...

Example#4 オープン型の使用

4 番目の例では、SDO オープン型および createDataObject() メソッドの使用法を説明します。 この例では、次のふたつのスキーマを使用します。

<schema
  xmlns="https://www.w3.org/2001/XMLSchema">

  <element name="jungle">
    <complexType>
      <sequence>
        <any minOccurs="0" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>

</schema>

定義の中に any 要素が存在することに注目しましょう。 この最初のスキーマでは、複合型 jungle を定義しています。その内容は、その他の任意の型のシーケンスです。 この例で使用している方は、2 番目のスキーマファイルで定義されています。

<schema xmlns= "https://www.w3.org/2001/XMLSchema">

   <complexType name="snakeType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "length" type="positiveInteger" />
     </sequence>
   </complexType>

   <complexType name="bearType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "weight" type="positiveInteger" />
     </sequence>
   </complexType>

   <complexType name="pantherType">
     <sequence>
       <element name= "name" type="string"/>
       <element name= "colour" type="string" />
     </sequence>
   </complexType>

</schema>

これらのふたつのスキーマファイルを使用する PHP コードの例は、次のようになります。

<?php

/**
 * オープン型および addTypes() メソッドの使用法
 */

$xmldas SDO_DAS_XML::create();
$xmldas->addTypes("jungle.xsd"); // これはオープン型です。つまり、
                                 // "any" 型を使用できることが
                                 // xsd ファイルで指定されています
$xmldas->addTypes('animalTypes.xsd');

$baloo            $xmldas->createDataObject('','bearType');
$baloo->name      "Baloo";
$baloo->weight    800;

$bagheera         $xmldas->createDataObject('','pantherType');
$bagheera->name   "Bagheera";
$bagheera->colour 'inky black';

$kaa              $xmldas->createDataObject('','snakeType');
$kaa->name        "Kaa";
$kaa->length      25;

$document         $xmldas->createDocument();
$do               $document->getRootDataObject();
$do->bear         $baloo;
$do->panther      $bagheera;
$do->snake        $kaa;

print(
$xmldas->saveString($document,2));

?>

これらのふたつのスキーマファイルは、 最初の create() および addTypes() メソッドで XML DAS に読み込まれます。 createDataObject() メソッドを使用して、 3 つに分かれたデータオブジェクトを作成します。それぞれについて、 名前空間 URI および型名が createDataObject() メソッドに渡されます。この例では、スキーマで名前空間が使用されていないため、 名前空間 URI は空の文字列です。bear (クマ)、panther (ヒョウ)、snake (ヘビ) を表す 3 つのデータオブジェクトが作成された後で、 createDocument() メソッドでドキュメントオブジェクトが作成されます。 この例の場合、ドキュメントの要素が何になるかは明確です。 2 番目のスキーマに含まれているのは複合型の定義のみであり、 ドキュメント要素は最初のスキーマに含まれているグローバルな jungle 要素だけだからです。 このドキュメントは 1 つのルートデータオブジェクトを保持しており、 これが空のドキュメント要素 jungle に対応しています。 この要素はオープン型なので、お好みのプロパティを追加することができます。 最初に代入が行われている部分が $do->bear で、 ここではルートデータオブジェクトにプロパティ bear が追加されています。それ以降の 2 つの代入についても同様です。 saveString() メソッドでドキュメントを書き出した結果は、 以下のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<jungle xsi:type="jungle" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance">
  <bear xsi:type="bearType">
    <name>Baloo</name>
    <weight>800</weight>
  </bear>
  <panther xsi:type="pantherType">
    <name>Bagheera</name>
    <colour>inky black</colour>
  </panther>
  <snake xsi:type="snakeType">
    <name>Kaa</name>
    <length>25</length>
  </snake>
</jungle>

Example#5 ドキュメントから何が得られるのかを知る

この例で説明しているのは、 XML Document オブジェクトから要素名および要素の名前空間を知る方法、 XML データオブジェクトのルートデータオブジェクトから SDO 型および名前空間を知る方法、 そしてそれらがお互いどのように関連しているかといった内容です。 これを理解するのは少し難しいかもしれません。というのも、ここでは 4 つのメソッドがコールされているからです。それらのうちの 2 つは Document オブジェクトに対するコールで、 残りの 2 つはルートデータオブジェクトを含む任意のデータオブジェクトに対するコールです。 XML モデルから SDO モデルを構築する際に定義されている規則のため、 もし今扱っているデータオブジェクトが ドキュメントのルートオブジェクトに対応するものならば、 これらの 4 つのメソッドコールから返される可能性のある値は 3 つだけです。

ドキュメントに対してコールされる 2 つのメソッドは、 getRootElementName() および getRootEelementURI() です。 これらはそれぞれ、要素名およびドキュメント要素の名前空間を返します。

任意のデータオブジェクトに対してコールされる 2 つのメソッドは、 getTypeName() および getTypeNamespaceURI() です。 これらはそれぞれ、SDO の型名およびデータオブジェクトの型の名前空間を返します。

ドキュメントオブジェクトに対して getRootElementURI() をコールした際の返り値は、ルートデータオブジェクトに対して getNamespaceURI() をコールした際の返り値と常に同じです。 本質的に、この情報はすべてスキーマファイルの最初の数行から得られるものです。 そこには 3 種類の情報が含まれています。 詳しく説明するために、もう一度ここで letter.xsd の最初の数行を示します。

<xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema"
            xmlns:letter="https://letterSchema"
            targetNamespace="https://letterSchema">

  <xsd:element name="letters" type="letter:FormLetter"/>

  <xsd:complexType name="FormLetter" mixed="true">
    .../...

重要な 3 つの値は以下のとおりです。

  • letters がドキュメント要素の名前です。

  • FormLetter がドキュメント要素の複合型の名前です。 これはまた、ルートデータオブジェクトの SDO 型の名前でもあります。

  • https://letterSchema がドキュメント要素の属する名前空間です。 これはまた、ルートデータオブジェクトの SDO 型の名前空間 URI でもあります。

XML-SDO 間の対応の規則により、 SDO モデルがスキーマファイルから作成される場合には ルート要素の型名および SDO 型の名前空間 URI は それが存在するドキュメント要素の複合型から取得されます。 したがって、この例ではルートデータオブジェクトの型名は FormLetter となります。 ドキュメント要素の複合型の定義が別に分かれておらずインラインで定義されており、 名前がつけられていない場合は、SDO の型名は要素名と同じになります。

次のプログラムは、letter ドキュメントを読み込んでから 4 つのコールの返り値を調べます。

<?php
/**
 * ドキュメントおよびドキュメント要素から得られる情報を調べます。
 * 4 種類のコールがあるため、理解するのは少し難しいでしょう。
 * ドキュメントに対するコールが 2 種類、
 * ルートデータオブジェクトおよびそのモデルに対するコールが 2 種類となります。
 * SDO-XML の対応規則および SDO モデルが XML モデルから作成されている
 * ということから、これらの 4 つのコールから得られる値は 3 つだけです。
 * 常に $document->getRootElementURI() == (ルートデータオブジェクトの型)->namespaceURI
 * となります。
 * 本質的に、これらはすべて xsd の最初の数行から得られるものです。
 * <xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema"
 *   xmlns:letter="https://letterSchema"
 *   targetNamespace="https://letterSchema">
 *   <xsd:element name="letters" type="letter:FormLetter"/>
 */

$xmldas SDO_DAS_XML::create("letter.xsd");
$document $xmldas->loadFile("letter.xml");
$root_do $document->getRootDataObject();

/**
 * "root element name" は、ドキュメント要素の要素名です。
 * この場合は 'letters' となります。
 * これは xsd のドキュメント要素の 'name' 属性と一致し、
 * xml の要素名とも一致します。
 */
echo "ドキュメント要素の名前は " $document->getRootElementName() . " です。\n";
assert($document->getRootElementName() == 'letters'); // ドキュメントのプロパティ

/**
 * "root element URI" は、ドキュメント要素の要素名の名前空間です。
 * この場合は 'https://letterSchema' となります。
 * というのも 'letters' がこの名前空間にあるからです。
 * これは xsd から得られ、xml から取得した名前空間と一致します。
 */
echo "ドキュメント要素の名前空間は " $document->getRootElementURI() . " です。\n";
assert($document->getRootElementURI() == 'https://letterSchema'); // ドキュメントのプロパティ

/**
 * 型名は SDO モデルから取得します。
 * XML-SDO の対応規則では、これは下のいずれかです。
 *   complexType が存在する場合は、その名前 (今回はこちらです)
 *   complexType がない場合は、ドキュメント要素の名前
 * これは xsd から得られます。
 */
echo "ルートデータオブジェクトの型名は " $root_do->getTypeName() . " です。\n";
assert($root_do->getTypeName() == 'FormLetter');

/**
 * 型の namespaceURI は SDO モデルから取得します。
 * XML-SDO の対応規則では、これは常にドキュメント要素の名前空間 URI と同じ
 * であることが保証されています。
 */
echo "ルートデータオブジェクトの namespaceURI は " $root_do->getTypeNamespaceURI() . " です。\n";
assert($root_do->getTypeNamespaceURI() == 'https://letterSchema');

?>

このプログラムの出力は次のようになります。

ドキュメント要素の名前は letters です。
ドキュメント要素の名前空間は https://letterSchema です。
ルートデータオブジェクトの型名は FormLetter です。
ルートデータオブジェクトの namespaceURI は https://letterSchema です。

Example#6 SDO モデルの表示

XML DAS に読み込まれた型やプロパティの情報を見るための簡単な手段が提供されています。 php の "print" あるいは "echo" を使用すると、型およびプロパティの情報が出力されます。

<?php
/**
 * モデルの情報の出力
 */

$xmldas SDO_DAS_XML::create("letter.xsd");
print 
$xmldas;

?>

このプログラムの出力は次のようになります。

object(SDO_XML_DAS)#1 {
18 types have been defined. The types and their properties are::
1. commonj.sdo:BigDecimal
2. commonj.sdo:BigInteger
3. commonj.sdo:Boolean
4. commonj.sdo:Byte
5. commonj.sdo:Bytes
6. commonj.sdo:ChangeSummary
7. commonj.sdo:Character
8. commonj.sdo:DataObject
9. commonj.sdo:Date
10. commonj.sdo:Double
11. commonj.sdo:Float
12. commonj.sdo:Integer
13. commonj.sdo:Long
14. commonj.sdo:Short
15. commonj.sdo:String
16. commonj.sdo:URI
17. https://letterSchema:FormLetter
    - date (commonj.sdo:String)
    - firstName (commonj.sdo:String)
    - lastName (commonj.sdo:String)
18. https://letterSchema:RootType
    - letters (https://letterSchema:FormLetter)

定義済みクラス

XML DAS は、主に 2 つのクラスから成り立っています。 ひとつめは SDO_DAS_XML で、XML ソースからデータを取得したり データを書き戻したりする際に使用するクラスです。 もうひとつが SDO_DAS_XML_Document クラスで、 これが XML ドキュメント内のデータを表します。

これ以外に、xsd や xml ファイルの検索・パース中にエラーが発生した場合にスローされる 例外クラスがいくつかあります。

SDO_DAS_XML

これが XML DAS の中心となるクラスです。 xml ソースからデータを取得したり、データを書き戻す際に使用します。 xml ファイルの読み込みや書き込み以外のメソッドもあります。

メソッド

  • create は SDO_DAS_XML クラスの静的メソッドです。 SDO_DAS_XML オブジェクトを作成するために使用します。

  • addTypescreate() と同じような動作をしますが、 これはすでに作成済みの XML DAS に対して後からスキーマファイルを追加します。

  • createDataObject は、指定した型の SDO データオブジェクトを作成するために使用します。

  • createDocument は、XML ドキュメントオブジェクトをスクラッチから作成するために使用します。

  • loadFile は、xml インスタンスドキュメントをファイルから読み込みます。 ローカルファイルシステム上、あるいはリモートホスト上のどちらのファイルも読み込み可能です。

  • loadString は上のメソッドと同じですが、これは xml インスタンスドキュメントを文字列から読み込みます。

  • saveFile は SDO_DAS_XML_Document オブジェクトを xml ファイルに保存します。

  • saveString は SDO_DAS_XML_Document オブジェクトを xml 文字列に保存します。

SDO_DAS_XML_Document

このクラスの使用目的は、ドキュメント要素の名前および名前空間を取得すること、 そしてドキュメントのルートデータオブジェクトを取得することです。 最後に、ドキュメントの出力時に XML のバージョンおよびエンコーディングを指定することもできます。

メソッド

SDO_DAS_XML_ParserException

SDO_Exception のサブクラスです。 xsd/xml ファイルの読み込み中にパースエラーが発生した場合にスローされます。

SDO_DAS_XML_FileException

SDO_Exception のサブクラスです。 ファイルからデータを読み込むメソッドで、 ファイルが見つからなかった場合にスローされます。

SDO 2.0 仕様と比較した場合の制限事項

» SDO 2.0 仕様 で、XML と SDO の間での型の対応が定義されています。 Java SDO では、この対応は XMLHelper で実装されています。 PHP 用の SDO では、この対応が XML データアクセスサービスで実装されています。 XML DAS の実装には、SDO 2.0 仕様で定義されている対応に対していくつか制限があります。 制限事項の詳細は以下のとおりです。

XML の単純な型
  1. Simple Type with sdoJava:instanceClass - PHP では同等の機能は提供されていません。

  2. Simple Type with sdoJava:extendedInstanceClass - PHP では同等の機能は提供されていません。

  3. Simple Type with list of itemType.

  4. Simple Type with union.

XML の複合型
  1. Complex Type with sdo:aliasName - PHP では SDO 型のエイリアスをサポートしていません。

XSD の属性
  1. Attribute with sdo:aliasName - PHP では SDO プロパティのエイリアスをサポートしていません。

  2. Attribute with default value - PHP では SDO プロパティのデフォルト値をサポートしていません。

  3. Attribute with fixed value - PHP では SDO の読み込み専用プロパティやデフォルト値をサポートしていません。

  4. Attribute referencing a DataObject with sdo:propertyType - sdo:propertyType="..." はサポートしていません。

  5. Attribute with bi-directional property to a DataObject with sdo:oppositeProperty and sdo:propertyType - PHP では SDO opposite をサポートしていません。

XSD の要素
  1. Element with sdo:aliasName - PHP では SDO プロパティのエイリアスをサポートしていません。

  2. Element with substitution group.

XSD Elements with Simple Type
  1. Element of SimpleType with default - PHP では SDO のデフォルト値をサポートしていません。

  2. Element of SimpleType with fixed value - PHP では SDO の読み込み専用プロパティやデフォルト値をサポートしていません。

  3. Element of SimpleType with sdo:string - sdo:string="true" はサポートしていません。

  4. Element referencing a DataObject with sdo:propertyType - sdo:propertyType="..." はサポートしていません。

  5. Element with bi-directional reference to a DataObject with sdo:oppositeProperty and sdo:propertyType - PHP では SDO opposite をサポートしていません。

目次