## シーケンスデータオブジェクトの使用

シーケンスデータオブジェクトは、データオブジェクト内のさまざまな プロパティの並び順を追跡する SDO です。ここには、非構造化 テキスト要素 (SDO のいずれのプロパティにも属さないテキスト要素) を含めることも可能です。シーケンスデータオブジェクトは、 非構造化テキストを許可 (つまり、mixed=true である) したり、要素が交互に現れる (

    <A/><B/><A/>

) ような XML 文書を扱う場合に有用です。 これは、例えば order に choice を指定した複合型の要素に対して スキーマで maxOccurs>1 を定義している場合などに発生します。

以下の例では、XML データアクセスサービスを使用して、 下のスキーマおよびインスタンスをもとに作成した SDO の使用を想定しています。

このスキーマでは、手紙の書式を定義しています。letter (手紙) には オプションで 3 つのプロパティ date (日付)、firstName (名前)、 および lastName (苗字) を含めることが可能です。このスキーマでは mixed="true" としていますが、これは 3 つのプロパティの間に非構造化テキストをちりばめることが できるということを意味します。

    <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>

以下が、手紙のインスタンスです。これには 3 つのプロパティ date、firstName および lastName が含まれており、非構造化 テキスト要素として住所と本文が含まれています。

    <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>

このインスタンスが読み込まれると、letter データオブジェクトの シーケンス番号およびプロパティ番号は以下の表のようになります。

シーケンスのインデックス | プロパティのインデックス:名前 | 値
--- | --- | ---
0 | 0:date | March 1, 2005
1 | - | Mutual of Omaha
2 | - | Wild Kingdom, USA
3 | - | Dear
4 | 1:firstName | Casy
5 | 2:lastName | Crocodile
6 | - | Please buy more shark repellent.
7 | - | Your premium is past due.

シーケンス番号の整合性を保つため、シーケンスデータオブジェクトの 操作には SDO_Sequence インターフェイスを使用しなければなりません。 これにより、データオブジェクトに対しての操作を プロパティのインデックスではなくシーケンスのインデックスを使用して 行えるようになります (上の表を参照ください)。 以下の例では、letter のインスタンスが データオブジェクト $letter として 読み込まれているものと仮定します。

例1 SDO_Sequence インターフェイスの取得

データオブジェクトのシーケンスを取得するには getSequence() メソッドを使用します。 以下の例では、letter データオブジェクトのシーケンスを取得します。

`<?php
$letter_seq = $letter->getSequence();
?>`

これ以降の例では、letter データオブジェクトのシーケンスが 変数 $letter_seq に代入されているものとします。

例2 シーケンスの値の取得/設定

シーケンスのインデックスを使用することで、(非構造化 テキストも含め) それぞれの値を取得したり設定したりすることが可能です。 以下の例では、ファーストネームを 'Snappy' に変更して シーケンスの最後の値 (非構造化テキスト 'Your premium is past due.') を取得します。

`<?php
$letter_seq[4] = 'Snappy';
$text = $letter_seq[count($letter_seq) - 1];
?>`

例3 シーケンスの繰り返し処理

foreach を使用して、個々のシーケンス値について処理を繰り返すことが できます。以下の例では、シーケンス順に個々の値を処理します。

`<?php
foreach ($letter->getSequence() as $value) {
// ...
}
?>`

例4 シーケンスとデータオブジェクトの比較

データオブジェクトのインターフェイスから設定した値は、シーケンスの 一部とはならないことがあります。データオブジェクト経由で値を 設定した場合、そのプロパティが既にシーケンスに組み込まれていた 場合にのみシーケンスからアクセス可能となります。 以下の例では、データオブジェクト経由で lastName を設定して それをシーケンスから取得しています。これがうまくいくのは、 lastName が既にシーケンス内に存在するからです。もしこれが 事前に設定されていなかった場合、lastName には 'Smith' が 設定されますが、それはシーケンスの一部とはなりません。

`<?php
$letter[2] = 'Smith';
$last_name = $letter_seq[5];
?>`

例5 シーケンスへの追加

シーケンスに新しい値を追加するには SDO_Sequence::insert() メソッドを使用します。以下の例では、プロパティ 'firstName' および 'lastName' が最初に削除されているものと仮定します。

`<?php
// シーケンスに firstName を追加します
// 値: 'Smith'
// シーケンスのインデックス: NULL (追加)
// プロパティ ID: 1 (firtName プロパティのインデックス)
$letter_seq->insert('Smith', NULL, 1);
// シーケンスに lastName を追加します
// 値: 'Jones'
// シーケンスのインデックス: NULL (追加)
// プロパティ ID: 'lastName' (lastName プロパティの名前)
$letter_seq->insert('Jones', NULL, 'lastName');
// 非構造化テキストを追加します
// 値: 'Cancel Subscription.'
// シーケンスのインデックス: 省略 (追加)
// プロパティ ID: 省略 (非構造化テキスト)
$letter_seq->insert('Cancel Subscription.');
// 非構造化テキストを間に挿入します。それ以降のシーケンス値は
// ひとつずれます。
// 値: 'Care of:'
// シーケンスのインデックス: 1 (2 番目の要素として挿入する)
// プロパティ ID: 省略 (非構造化テキスト)
$letter_seq->insert('Care of:', 1);
?>`

例6 シーケンスからの削除

シーケンスに項目が登録されているかどうかを確かめたり シーケンスから項目を削除したりする際には、それぞれ isset() および unset() 関数が使用可能です (注意: unset() は、現時点では値を データオブジェクト内に残します。しかし、この挙動はおそらく今後 変更され、データオブジェクトからもデータを削除することに なるでしょう)。シーケンスの挙動は、リスト構造に似ています。 そのため、シーケンスの途中の項目を削除すると、それ以降の インデックスがひとつずつ小さいほうにずれます。以下の例では、 インデックスの最初の要素が存在するかどうか調べ、存在する場合に それを削除しています。

`<?php
if (isset($letter_seq[0])) {
unset($letter_seq[0]);
}
?>`