PHP Unconference Europe 2015

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

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:letter="http://letterSchema"
  targetNamespace="http://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="http://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>

例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="http://letterSchema" xsi:type="FormLetter" xmlns:xsi="http://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>

例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="http://letterSchema" xsi:type="FormLetter" 
xmlns:xsi="http://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>

例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"?>
.../...

例4 オープン型の使用

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

<schema
  xmlns="http://www.w3.org/2001/XMLSchema">
  
  <element name="jungle">
    <complexType>
      <sequence>
        <any minOccurs="0" maxOccurs="unbounded"/>
      </sequence>
    </complexType>
  </element>
  
</schema>

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

<schema xmlns= "http://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="http://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>

例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="http://www.w3.org/2001/XMLSchema"
            xmlns:letter="http://letterSchema"
            targetNamespace="http://letterSchema">
            
  <xsd:element name="letters" type="letter:FormLetter"/>
  
  <xsd:complexType name="FormLetter" mixed="true">
    .../...

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

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

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

  • http://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="http://www.w3.org/2001/XMLSchema"
 *   xmlns:letter="http://letterSchema"
 *   targetNamespace="http://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" は、ドキュメント要素の要素名の名前空間です。
 * この場合は 'http://letterSchema' となります。
 * というのも 'letters' がこの名前空間にあるからです。
 * これは xsd から得られ、xml から取得した名前空間と一致します。
 */
echo "ドキュメント要素の名前空間は " $document->getRootElementURI() . " です。\n";
assert($document->getRootElementURI() == 'http://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() == 'http://letterSchema'); 

?>

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

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

例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. http://letterSchema:FormLetter
    - date (commonj.sdo:String)
    - firstName (commonj.sdo:String)
    - lastName (commonj.sdo:String)
18. http://letterSchema:RootType
    - letters (http://letterSchema:FormLetter)
add a note add a note

User Contributed Notes 1 note

up
0
cc at yarmschool dot org
16 days ago
Hello. I need to know if I could this with PHP under Windows IIS servers. Thank you
To Top