スキーマ セクションが必要です。 前の例に示すように、ADO は各列に関する詳細なメタデータを書き込み、更新のために可能な限りデータ値のセマンティクスを保持します。 ただし、XML に読み込むには、ADO で必要なのは列の名前と、それらが属する行セットだけです。 最小スキーマの例を次に示します。
<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:rs="urn:schemas-microsoft-com:rowset"
xmlns:z="#RowsetSchema">
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly">
<s:AttributeType name="ShipperID"/>
<s:AttributeType name="CompanyName"/>
<s:AttributeType name="Phone"/>
<s:Extends type="rs:rowbase"/>
</s:ElementType>
</s:Schema>
<rs:data>
...
</rs:data>
</xml>
前の例では、ADO は型情報がスキーマに含まれていないため、データを可変長文字列として扱います。
列名のエイリアスの作成
rs:name 属性を使用すると、行セットによって公開される列情報にフレンドリ名が表示され、データ セクションで短い名前を使用できるように、列名の別名を作成できます。 たとえば、次のように、前のスキーマを変更して ShipperID を s1 に、CompanyName を s2 に、Phone を s3 にマップできます。
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly" rs:updatable="true">
<s:AttributeType name="s1" rs:name="ShipperID" rs:number="1" ...>
...
</s:AttributeType>
<s:AttributeType name="s2" rs:name="CompanyName" rs:number="2" ...>
...
</s:AttributeType>
<s:AttributeType name="s3" rs:name="Phone" rs:number="3" ...>
...
</s:AttributeType>
...
</s:ElementType>
</s:Schema>
次に、データ セクションで、行は (rs:name ではなく) name 属性を使用してその列を参照します。
"<row s1="1" s2="Speedy Express" s3="(503) 555-9831"/>
列名が XML の有効な属性またはタグ名でない場合は常に、列名の別名を作成する必要があります。 たとえば、スペースが埋め込まれた名前は無効な属性であるため、"LastName" にはエイリアスが必要です。 次の行は XML パーサーによって正しく処理されないため、埋め込みスペースのない他の名前のエイリアスを作成する必要があります。
<row last name="Jones"/>
name 属性に使用する値は、XML ドキュメントのスキーマ セクションとデータ セクションの両方で列が参照される各場所で一貫して使用する必要があります。 s1 の一貫した使用例を次に示します。
<s:Schema id="RowsetSchema">
<s:ElementType name="row" content="eltOnly">
<s:attribute type="s1"/>
<s:attribute type="CompanyName"/>
<s:attribute type="s3"/>
<s:extends type="rs:rowbase"/>
</s:ElementType>
<s:AttributeType name="s1" rs:name="ShipperID" rs:number="1"
rs:maydefer="true" rs:writeunknown="true">
<s:datatype dt:type="i4" dt:maxLength="4" rs:precision="10"
rs:fixedlength="true" rs:maybenull="true"/>
</s:AttributeType>
</s:Schema>
<rs:data>
<z:row s1="1" CompanyName="Speedy Express" s3="(503) 555-9831"/>
</rs:data>
同様に、前の例では CompanyName に対してエイリアスが定義されていないため、CompanyName はドキュメント全体で一貫して使用する必要があります。
データ型
dt:type 属性を持つ列にデータ型を適用できます。 使用できる XML 型の詳細なガイドについては、W3C XML-Data 仕様の「データ型」セクションを参照してください。 データ型は、2 つの方法で指定できます。列定義自体に直接 dt:type 属性を指定するか、列定義の入れ子になった要素として s:datatype コンストラクトを使用します。 例えば
<s:AttributeType name="Phone" >
<s:datatype dt:type="string"/>
</s:AttributeType>
は、次の値に相当します。
<s:AttributeType name="Phone" dt:type="string"/>
dt:type 属性を行定義から完全に省略した場合、既定では、列の型は可変長文字列になります。
型名 (dt:maxLength など) よりも多くの型情報がある場合は、s:datatype 子要素を使用する方が読みやすくなります。 ただし、これは単なる規則であり、要件ではありません。
次の例では、スキーマに型情報を含める方法について詳しく説明します。
<!-- 1. String with no max length -->
<s:AttributeType name="title_id"/>
<!-or -->
<s:AttributeType name="title_id" dt:type="string"/>
<!-- 2. Fixed length string with max length of 6 -->
<s:AttributeType name="title_id">
<s:datatype dt:type="string" dt:maxLength="6" rs:fixedlength="true" />
</s:AttributeType>
<!-- 3. Variable length string with max length of 6 -->
<s:AttributeType name="title_id">
<s:datatype dt:type="string" dt:maxLength="6" />
</s:AttributeType>
<!-- 4. Integer -->
<s:AttributeType name="title_id" dt:type="int"/>
2 番目の例では、rs:fixedlength 属性が微妙に使用されています。 rs:fixedlength 属性が true に設定されている列は、データの長さがスキーマで定義されている必要があることを意味します。 この場合、title_idの有効な値は "123456" であり、"123." です。ただし、長さが 6 ではなく 3 であるため、"123" は有効ではありません。 fixedlength プロパティの詳細については、OLE DB プログラマ ガイドを参照してください。
Null の処理
null 値は rs:maybenull 属性によって処理されます。 この属性が true に設定されている場合、列の内容に null 値を含めることができます。 さらに、列がデータの行に見つからない場合、ユーザーが行セットからデータを読み取ると、IRowset::GetData() から null 値を返されます。 Shippers テーブルの次の列定義について考えてみましょう。
<s:AttributeType name="ShipperID">
<s:datatype dt:type="int" dt:maxLength="4"/>
</s:AttributeType>
<s:AttributeType name="CompanyName">
<s:datatype dt:type="string" dt:maxLength="40" rs:maybenull="true"/>
</s:AttributeType>
定義では CompanyName を null にできますが、ShipperID に null 値を含めることはできません。 データ セクションに次の行が含まれている場合、永続化プロバイダーは、CompanyName 列のデータの状態を OLE DB 状態定数DBSTATUS_S_ISNULLに設定します。
<z:row ShipperID="1"/>
行が完全に空の場合、次のように、永続化プロバイダーは ShipperID に対して DBSTATUS_E_UNAVAILABLE を返し、CompanyName に対して DBSTATUS_S_ISNULL の OLE DB 状態を返します。
<z:row/>
長さ 0 の文字列は null と同じではないことに注意してください。
<z:row ShipperID="1" CompanyName=""/>
前の行の場合、永続化プロバイダーは、両方の列に対して OLE DB の状態DBSTATUS_S_OKを返します。 この場合の CompanyName は、単に "" (長さ 0 の文字列) です。
OLE DB の XML ドキュメントのスキーマ内で使用できる OLE DB コンストラクトの詳細については、"urn:schemas-microsoft-com:rowset" の定義と OLE DB プログラマ ガイドを参照してください。