53
VS 2005 資料 【電脳梁山泊 烏賊塾】 -1- DataSet に依る XML の操作 XML ファイルを読み込む DataSet XML ファイルを読み込むには、ReadXml メソッドを使用する。 ReadXml は複数のオーバーロードが有るが、此処ではファイル名を指定して読み込む方法を紹介する。 Visual Basic Dim dtSet As New DataSet ' XML ファイルを読み込む dtSet.ReadXml("C:¥Work¥Test.xml") C# DataSet dtSet = new DataSet( ); // XML ファイルを読み込む dtSet.ReadXml(@"C:¥Work¥Test.xml"); DataSet に格納されて居るデータの XML 表現を取得する DataSet に格納されて居るデータの XML 表現を取得するには、GetXML メソッドを使用する。 Visual Basic Dim dtSet As DataSet = New DataSet("ADDRESS_BOOK") Dim dtTbl As DataTable = dtSet.Tables.Add("ADDRESS_LIST") dtTbl.Columns.Add("ZIP_CODE", Type.GetType("System.String")) dtTbl.Columns.Add("ADDRESS", Type.GetType("System.String")) ' データセットにデータを構築 Dim row As DataRow Dim i As Integer For i = 1 To 5 row = dtTbl.NewRow( ) row("ZIP_CODE") = i.ToString( ).PadLeft(3, i.ToString( )) & "-" & _ i.ToString( ).PadLeft(4, i.ToString( )) row("ADDRESS") = "東京都渋谷区" & i.ToString( ) & "丁目" dtTbl.Rows.Add(row) Next ' DataSet 内のデータの XML 表現を取得 Console.WriteLine(dtSet.GetXml( )) C# DataSet dtSet = new DataSet("ADDRESS_BOOK"); DataTable dtTbl = dtSet.Tables.Add("ADDRESS_LIST"); dtTbl.Columns.Add("ZIP_CODE", typeof(string)); dtTbl.Columns.Add("ADDRESS", typeof(string)); // データセットにデータを構築 DataRow row; for (int i = 1; i < 5; i++)

DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-1-

■ DataSet に依る XML の操作 ■

■ XML ファイルを読み込む

DataSet に XML ファイルを読み込むには、ReadXml メソッドを使用する。

ReadXmlは複数のオーバーロードが有るが、此処ではファイル名を指定して読み込む方法を紹介する。

Visual Basic

Dim dtSet As New DataSet

' XML ファイルを読み込む

dtSet.ReadXml("C:¥Work¥Test.xml")

C#

DataSet dtSet = new DataSet( );

// XML ファイルを読み込む

dtSet.ReadXml(@"C:¥Work¥Test.xml");

■ DataSet に格納されて居るデータの XML 表現を取得する

DataSet に格納されて居るデータの XML 表現を取得するには、GetXML メソッドを使用する。

Visual Basic

Dim dtSet As DataSet = New DataSet("ADDRESS_BOOK")

Dim dtTbl As DataTable = dtSet.Tables.Add("ADDRESS_LIST")

dtTbl.Columns.Add("ZIP_CODE", Type.GetType("System.String"))

dtTbl.Columns.Add("ADDRESS", Type.GetType("System.String"))

' データセットにデータを構築

Dim row As DataRow

Dim i As Integer

For i = 1 To 5

row = dtTbl.NewRow( )

row("ZIP_CODE") = i.ToString( ).PadLeft(3, i.ToString( )) & "-" & _

i.ToString( ).PadLeft(4, i.ToString( ))

row("ADDRESS") = "東京都渋谷区" & i.ToString( ) & "丁目"

dtTbl.Rows.Add(row)

Next

' DataSet 内のデータの XML 表現を取得

Console.WriteLine(dtSet.GetXml( ))

C#

DataSet dtSet = new DataSet("ADDRESS_BOOK");

DataTable dtTbl = dtSet.Tables.Add("ADDRESS_LIST");

dtTbl.Columns.Add("ZIP_CODE", typeof(string));

dtTbl.Columns.Add("ADDRESS", typeof(string));

// データセットにデータを構築

DataRow row;

for (int i = 1; i < 5; i++)

デデーータタセセッットト

Page 2: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-2-

{

row = dtTbl.NewRow( );

row["ZIP_CODE"] = i.ToString( ).PadLeft(3, i.ToString( )[0]) + "-" +

i.ToString( ).PadLeft(4, i.ToString( )[0]);

row["ADDRESS"] = "東京都渋谷区" + i.ToString( ) + "丁目";

dtTbl.Rows.Add(row);

}

// DataSet 内のデータの XML 表現を取得

Console.WriteLine(dtSet.GetXml( ));

取得した DataSet 内のデータの XML 表現

<ADDRESS_BOOK>

<ADDRESS_LIST>

<ZIP_CODE>111-1111</ZIP_CODE>

<ADDRESS>東京都渋谷区 1 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>222-2222</ZIP_CODE>

<ADDRESS>東京都渋谷区 2 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>333-3333</ZIP_CODE>

<ADDRESS>東京都渋谷区 3 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>444-4444</ZIP_CODE>

<ADDRESS>東京都渋谷区 4 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>555-5555</ZIP_CODE>

<ADDRESS>東京都渋谷区 5 丁目</ADDRESS>

</ADDRESS_LIST>

</ADDRESS_BOOK>

■ DataSet のスキーマを取得しファイルへ書き込む

DataSet のスキーマを取得しファイルへ書き込むには WriteXmlSchema メソッドを使用する。

サンプルでは、データセットにデータをセットし、其のスキーマをファイルへ書き出して居る。

Visual Basic

Dim dtSet As DataSet = New DataSet("ADDRESS_BOOK")

Dim dtTbl As DataTable = dtSet.Tables.Add("ADDRESS_LIST")

dtTbl.Columns.Add("ZIP_CODE", Type.GetType("System.String"))

dtTbl.Columns.Add("ADDRESS", Type.GetType("System.String"))

' データセットにデータを構築

Dim row As DataRow

Dim i As Integer

For i = 1 To 5

row = dtTbl.NewRow( )

row("ZIP_CODE") = i.ToString( ).PadLeft(3, i.ToString( )) & "-" & _

Page 3: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-3-

i.ToString( ).PadLeft(4, i.ToString( ))

row("ADDRESS") = "東京都渋谷区" & i.ToString( ) & "丁目"

dtTbl.Rows.Add(row)

Next

' スキーマファイルを作成

dtSet.WriteXmlSchema("C:¥Work¥Schema.xsd")

C#

DataSet dtSet = new DataSet("ADDRESS_BOOK");

DataTable dtTbl = dtSet.Tables.Add("ADDRESS_LIST");

dtTbl.Columns.Add("ZIP_CODE", typeof(string));

dtTbl.Columns.Add("ADDRESS", typeof(string));

// データセットにデータを構築

DataRow row;

for (int i = 1; i < 5; i++)

{

row = dtTbl.NewRow( );

row["ZIP_CODE"] = i.ToString( ).PadLeft(3, i.ToString( )[0]) + "-" +

i.ToString( ).PadLeft(4, i.ToString( )[0]);

row["ADDRESS"] = "東京都渋谷区" + i.ToString( ) + "丁目";

dtTbl.Rows.Add(row);

}

// スキーマファイルを作成

dtSet.WriteXmlSchema(@"C:¥Work¥Schema.xsd");

作成されたスキーマ

<?xml version="1.0" standalone="yes"?>

<xs:schema id="ADDRESS_BOOK" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="ADDRESS_BOOK" msdata:IsDataSet="true"

msdata:UseCurrentLocale="true">

<xs:complexType>

<xs:choice minOccurs="0" maxOccurs="unbounded">

<xs:element name="ADDRESS_LIST">

<xs:complexType>

<xs:sequence>

<xs:element name="ZIP_CODE" type="xs:string" minOccurs="0" />

<xs:element name="ADDRESS" type="xs:string" minOccurs="0" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

■ スキーマファイルを読み込み DataSet に適用する

スキーマファイルを読み込んで DataSet に適用するには、ReadXmlSchema メソッドを使用する。

亦、現在 DataSet に適用されて居るスキーマを確認するには GetXmlSchema を使用する。

Page 4: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-4-

GetXmlSchema メソッドは、スキーマ文字列を返す。

Visual Basic

Dim dtSet As New DataSet( )

' スキーマファイルの読み込み

dtSet.ReadXmlSchema("C:¥Work¥Schema.xsd")

' 適用したスキーマの確認

Console.WriteLine(dtSet.GetXmlSchema( ))

C#

DataSet dtSet = new DataSet( );

// スキーマファイルの読み込み

dtSet.ReadXmlSchema(@"C:¥Work¥Schema.xsd");

// 適用したスキーマの確認

Console.WriteLine(dtSet.GetXmlSchema( ));

スキーマファイル

'Schema.xsd

<?xml version="1.0" standalone="yes"?>

<xs:schema id="ADDRESS_BOOK" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="ADDRESS_BOOK" msdata:IsDataSet="true"

msdata:UseCurrentLocale="true">

<xs:complexType>

<xs:choice minOccurs="0" maxOccurs="unbounded">

<xs:element name="ADDRESS_LIST">

<xs:complexType>

<xs:sequence>

<xs:element name="ZIP_CODE" type="xs:string" minOccurs="0" />

<xs:element name="ADDRESS" type="xs:string" minOccurs="0" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

■ DataSet の内容から XML ファイルを作成する

DataSet の内容から XML ファイルを作成するには、WriteXml メソッドを使用する。

Visual Basic

Dim dtSet As DataSet = New DataSet("ADDRESS_BOOK")

Dim dtTbl As DataTable = dtSet.Tables.Add("ADDRESS_LIST")

dtTbl.Columns.Add("ZIP_CODE", Type.GetType("System.String"))

dtTbl.Columns.Add("ADDRESS", Type.GetType("System.String"))

' データセットにデータを構築

Dim row As DataRow

Dim i As Integer

For i = 1 To 5

Page 5: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-5-

row = dtTbl.NewRow( )

row("ZIP_CODE") = i.ToString( ).PadLeft(3, i.ToString( )) & "-" & _

i.ToString( ).PadLeft(4, i.ToString( ))

row("ADDRESS") = "東京都渋谷区" & i.ToString( ) & "丁目"

dtTbl.Rows.Add(row)

Next

' XML ファイルへ書き出す

dtSet.WriteXml("C:¥Work¥AddressList.xml")

C#

DataSet dtSet = new DataSet("ADDRESS_BOOK");

DataTable dtTbl = dtSet.Tables.Add("ADDRESS_LIST");

dtTbl.Columns.Add("ZIP_CODE", typeof(string));

dtTbl.Columns.Add("ADDRESS", typeof(string));

// データセットにデータを構築

DataRow row;

for (int i = 1; i < 5; i++)

{

row = dtTbl.NewRow( );

row["ZIP_CODE"] = i.ToString( ).PadLeft(3, i.ToString( )[0]) + "-" +

i.ToString( ).PadLeft(4, i.ToString( )[0]);

row["ADDRESS"] = "東京都渋谷区" + i.ToString( ) + "丁目";

dtTbl.Rows.Add(row);

}

// XML ファイルへ書き出す

dtSet.WriteXml(@"C:¥Work¥AddressList.xml");

作成した XML ファイル(AddressList.xml)

<?xml version="1.0" standalone="yes"?>

<ADDRESS_BOOK>

<ADDRESS_LIST>

<ZIP_CODE>111-1111</ZIP_CODE>

<ADDRESS>東京都渋谷区 1 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>222-2222</ZIP_CODE>

<ADDRESS>東京都渋谷区 2 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>333-3333</ZIP_CODE>

<ADDRESS>東京都渋谷区 3 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>444-4444</ZIP_CODE>

<ADDRESS>東京都渋谷区 4 丁目</ADDRESS>

</ADDRESS_LIST>

<ADDRESS_LIST>

<ZIP_CODE>555-5555</ZIP_CODE>

<ADDRESS>東京都渋谷区 5 丁目</ADDRESS>

</ADDRESS_LIST>

</ADDRESS_BOOK>

Page 6: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-6-

■ DataSet での XML の使用 ■

ADO.NET では、XML ストリームや XML ドキュメントから DataSet にデータを格納出来る。DataSet

にデータやスキーマ情報を格納するには、XML ストリームや XML ドキュメントを使用する。XML ス

トリームやXMLドキュメントから提供される情報をDataSetの既存のデータやスキーマ情報と組み合

わせる事も出来る。

ADO.NETでは、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

此の DataSet を HTTP 経由で転送する為、DataSet の XML 表現を作成出来る。此の時、DataSet に

スキーマが含まれて居ても、含まれて居なくても構わない。DataSet の XML 表現では、データを XML

で記述する。XML 表現にスキーマをインラインで含める場合は、此のスキーマを XML スキーマ定義言

語(XSD)で記述する。XML 及び XML スキーマには、リモートクライアントとの間で DataSet の内

容を転送する為の便利な書式が用意されて居る。

■ DiffGram

DiffGram は、データ要素の現在のバージョンと元のバージョンを識別する XML 形式で有る。DataSet

では、DataSet の内容を読み込んで永続化する為、亦、ネットワーク接続経由で転送する場合に此の内

容をシリアル化する為に、DiffGram 形式が使用される。DiffGram と仕て作成された DataSet は、ス

キーマを使用せずに DataSet の内容を正確に再作成する為に必要な総ての情報を DiffGram に格納す

る。此の様な情報には、Original 行バージョンと Current 行バージョンの両方の列値、行エラー情報、

行順序等が含まれて居る。

XML Web サービスから DataSet を送信、又は、取得する時には、DiffGram 形式が暗黙的に使用され

る。亦、ReadXml メソッドを使用して XML から DataSet の内容を読み取る時や、WriteXml メソッド

を使用して XML に DataSet の内容を書き込む時は、読み取りや書き込みの形式と仕て DiffGram を選

択出来る。詳細に付いては、「XML からの DataSet の読み込み」及び「XML データと仕ての DataSet

の書き込み」を参照され度い。

.NET Framework では、DiffGram 形式は、主に DataSet の内容をシリアル化する時の形式と仕て使用

されるが、Microsoft SQL Server データベース内のテーブルデータを変更する時にも DiffGrams を使

用出来る。

DiffGram 形式

DiffGram 形式は、現在のデータ、元のデータ(又は、前のデータ)、エラーの 3 つのセクションから構

成されて居る。DiffGram の例を次に示す。

<?xml version="1.0"?>

<diffgr:diffgram

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"

xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"

xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<DataInstance>

</DataInstance>

<diffgr:before>

</diffgr:before>

<diffgr:errors>

</diffgr:errors>

Page 7: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-7-

</diffgr:diffgram>

DiffGram 形式を構成するデータブロックに付いて次に説明する。

<DataInstance>

此のドキュメントでは、説明の目的で此の要素の名前である DataInstance を使用する。DataInstance

要素は、DataTable の行、又は、DataSet を表す。実際には DataInstance の代わりに DataSet 又は

DataTable の名前が此の要素に含まれる。DiffGram 形式の此のブロックには、現在のデータが含まれ

て居る。現在のデータは、変更されて居る場合と未変更の場合が有る。変更されて居る要素(行)を識

別する為、此の様な要素には diffgr:hasChanges 注釈が付く。

<diffgr:before>

DiffGram 形式の此のブロックには、行の元の内容が含まれて居る。此のブロックの要素は、diffgr:id

注釈を使用して DataInstance ブロックの内容と対応して居る。

<diffgr:errors>

DiffGram 形式の此のブロックには、DataInstance ブロックの特定の行に関するエラー情報が含まれて

居る。此のブロックの要素は、diffgr:id 注釈を使用して DataInstance ブロックの内容と対応して居る。

DiffGram 注釈

DiffGram では、DataSet の行バージョンやエラー情報を表す様々な DiffGram ブロックの要素を関連

付ける為、幾つかの注釈が使用される。

DiffGram 名前空間 urn:schemas-microsoft-com:xml-diffgram-v1 で定義されて居る DiffGram 注釈を

次の表に示す。

注釈 説明

id <diffgr:before>ブロックと<diffgr:errors>ブロックの要素を<DataInstance>ブロック

の要素と対応させる為に使用される。diffgr:id注釈の値は[TableName][RowIdentifier]

と謂う形式で指定される。次に例を示す。<Customers diffgr:id="Customers1">.

parentId 現在の要素の親要素で有る <DataInstance>ブロックの要素を識別する。

diffgr:parentId 注釈の値は[TableName][RowIdentifier]と謂う形式で指定される。次

に例を示す。<Orders diffgr:parentId="Customers1">.

hasChanges <DataInstance>ブロックの行を変更済みと仕て識別する。hasChanges 注釈には、次

の 3 つの孰れかの値を指定出来る。

inserted

Added 行を識別する。

modified

対応する<Original>行バージョンが<diffgr:before>ブロックに含まれて居る Modified

行を識別する。Deleted 行の場合、対応する Original 行バージョンが<diffgr:before>

ブロックには存在するが、<DataInstance>ブロックには注釈付き要素が存在しない。

descent

親子のリレーションシップに有る 1 つ以上の子要素が変更された親要素を識別する。

hasErrors <DataInstance>ブロック内で RowError が有る行を識別する。エラー要素は

<diffgr:errors>ブロックに挿入される。

Error <diffgr:errors>ブロック内の特定の要素に関する RowError のテキストが含まれて居

る。

DataSet の内容が DiffGram と仕て読み取られる、又は、書き込まれる時には、上記以外の注釈も含ま

れる。名前空間 urn:schemas-microsoft-com:xml-msdata で定義されて居る追加の注釈を次の表に示す。

Page 8: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-8-

注釈 説明

RowOrder 元のデータの行順序を保持し、特定の DataTable の行のインデックスを識別する。

Hidden 特定の列を ColumnMapping プロパティが MappingType.Hidden に設定されて居る列

と仕て識別する。此の属性は、msdata:hidden[ColumnName]="value"と謂う形式で指

定される。次に例を示す。

<Customers diffgr:id="Customers1" msdata:hiddenContactTitle="Owner">.

データが格納されて居る隠し列丈が DiffGram 属性と仕て書き込まれる。其れ以外の場

合は無視される。

DiffGram のサンプル

DiffGram 形式の例を次に示す。此の例では、変更のコミット前のテーブル内の行に対する更新結果が

示されて居る。CustomerID の ALFKI で有る行は変更されて居るが、更新されて居ない。此の為、

<DataInstance>ブロックに diffgr:id が Customers1 の Current 行が有り、<diffgr:before>ブロックに

diffgr:id が Customers1 の Original 行が有る。CustomerID が ANATR で有る行には RowError が含

まれて居る為、此の行には diffgr:hasErrors="true"と謂う注釈が付いて居る。<diffgr:errors>ブロック

に、此の行に関連する要素が有る。

<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"

xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

<CustomerDataSet>

<Customers diffgr:id="Customers1" msdata:rowOrder="0" diffgr:hasChanges="modified">

<CustomerID>ALFKI</CustomerID>

<CompanyName>New Company</CompanyName>

</Customers>

<Customers diffgr:id="Customers2" msdata:rowOrder="1" diffgram:hasErrors="true">

<CustomerID>ANATR</CustomerID>

<CompanyName>Ana Trujillo Emparedados y Helados</CompanyName>

</Customers>

<Customers diffgr:id="Customers3" msdata:rowOrder="2">

<CustomerID>ANTON</CustomerID>

<CompanyName>Antonio Moreno Taquera</CompanyName>

</Customers>

<Customers diffgr:id="Customers4" msdata:rowOrder="3">

<CustomerID>AROUT</CustomerID>

<CompanyName>Around the Horn</CompanyName>

</Customers>

</CustomerDataSet>

<diffgr:before>

<Customers diffgr:id="Customers1" msdata:rowOrder="0">

<CustomerID>ALFKI</CustomerID>

<CompanyName>Alfreds Futterkiste</CompanyName>

</Customers>

</diffgr:before>

<diffgr:errors>

<Customers diffgr:id="Customers2" diffgr:Error="An optimistic concurrency violation has

occurred for this row."/>

</diffgr:errors>

</diffgr:diffgram>

Page 9: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-9-

■ XML からの DataSet の読み込み

ADO.NET では、XML ストリームや XML ドキュメントから DataSet の内容を作成出来る。亦、.NET

Framework では、XML から読み込まれる情報と DataSet のスキーマやリレーショナル構造の作成方

法を柔軟に変更出来る。

DataSet に XML のデータを格納するには、DataSet オブジェクトの ReadXml メソッドを使用する。

ReadXml メソッドは、ファイル、ストリーム、又は、XmlReader からデータを読み取り、XML のソ

ースを引数と仕て受け取る。亦、XmlReadMode 引数を受け取る事も有る。XmlReader に関する詳細

に付いては、「XmlTextReader に依る XML データの読み取り」を参照され度い。ReadXml メソッドは、

XML ストリームや XML ドキュメントの内容を読み取り、DataSet にデータを読み込む。亦、指定さ

れて居る XmlReadMode と、リレーショナルスキーマが既に存在して居るか何うかに応じて、DataSet

のリレーショナルスキーマも作成する。

XmlReadMode 引数のオプションを次の表に示す。

オプション 説明

Auto 此れは、既定の設定で有る。XML を調べ、次の順序で最適なオプションを選択す

る。

・XML が DiffGram の場合は、DiffGram が使用される。

・DataSet にスキーマが含まれて居る場合、又は、XML にインラインスキーマが

含まれて居る場合は、ReadSchema が使用される。

・DataSet にスキーマが含まれて居らず、XML にインラインスキーマが含まれて

居ない場合は、InferSchema が使用される。

読み取られる XML の形式が判明して居る場合は、パフォーマンスを最大限に引き

出す為、既定値 Auto を使用する代わりに、XmlReadMode を明示的に設定する事

を推奨する。

ReadSchema インラインスキーマを読み取り、データとスキーマを読み込む。

DataSet に既にスキーマが含まれて居る場合には、読み取るインラインスキーマの

新しいテーブルが DataSet の既存のスキーマに追加される。インラインスキーマの

テーブルが既に DataSet に存在して居る場合には、例外がスローされる。

XmlReadMode.ReadSchema を使用して既存のテーブルのスキーマを修正出来な

い。

DataSet にスキーマが含まれて居らず、インラインスキーマが存在しない場合に

は、データは読み取られない。

インラインスキーマを定義するには、XML スキーマ定義言語(XSD)スキーマを

使用する。XML スキーマと仕てのインラインスキーマを書き込む方法の詳細に付

いては、「XML スキーマ(XSD)からの DataSet リレーショナル構造の生成」を

参照され度い。

IgnoreSchema インラインスキーマを無視し、データを既存の DataSet スキーマへ読み込む。既存

のスキーマに一致しないデータは破棄される。DataSet にスキーマが無い場合に

は、データは読み込まれない。

データが DiffGram の場合、IgnoreSchema は DiffGram と同様に機能する。

InferSchema インラインスキーマを無視し、XML データ構造毎にスキーマを推論し、データを

読み込む。

DataSet に既にスキーマが含まれて居る場合、現在のスキーマを拡張する為、既存

のテーブルに列が追加される。既存のテーブルが無い場合には、新しいテーブルが

追加される。推論されたテーブルが他の名前空間に既に存在して居る場合、又は、

推論された列と既存の列が矛盾する場合には、例外がスローされる。

ReadXmlSchema に依るXMLドキュメントからのスキーマの推論方法の詳細に付

いては、「XML からの DataSet リレーショナル構造の推論」を参照され度い。

Page 10: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-10-

DiffGram DiffGram を読み取り、現在のスキーマへデータを追加する。DiffGram は、既存の

行に対し、固有の識別子の値が一致する新しい行を結合する。此の資料の最後に有

る「XML のデータの結合」の説明を参照され度い。DiffGrams の詳細に付いては、

「DiffGram」を参照され度い。

Fragment ストリームの終わりに達する迄、複数 XML フラグメントの読み取りを続行する。

DataSet スキーマに一致するフラグメントが適切なテーブルに追加される。

DataSet スキーマに一致しないフラグメントは破棄される。

メモ: XMLドキュメントにアクセスする為のオブジェクトで有る ReadXml に XmlReader を渡すと、

ReadXml は次の要素ノードを読み取り、此のノードをルート要素と仕て処理し、此のノードの終わり

に到達する迄、読み取る。但し、XmlReadMode.Fragment を指定する場合には此れは該当しない。

DTD エンティティ

ドキュメント型定義(DTD)スキーマで定義されて居るエンティティが、XML に含まれて居る場合に、

ファイル名、ストリーム、又は、非検証 XmlReader を ReadXml に渡して DataSet を読み込むと、例

外がスローされる。此の方法の代わりに、EntityHandling を EntityHandling.ExpandEntities に設定

して XmlValidatingReader を作成し、XmlValidatingReader を ReadXml へ渡す様にする。

XmlValidatingReader に依ってエンティティが展開された後で、DataSet が此のエンティティを読み取

る。

XMLストリームからDataSetを読み込むコード例を次に示す。1番目の例では、ファイル名がReadXml

メソッドに渡される。2 番目の例では、XML が含まれて居る文字列が StringReader に依って読み込ま

れる。

Visual Basic

Dim dataSet As DataSet = New DataSet

dataSet.ReadXml("input.xml", XmlReadMode.ReadSchema)

C#

DataSet dataSet = new DataSet( );

dataSet.ReadXml("input.xml", XmlReadMode.ReadSchema);

Visual Basic

Dim dataSet As DataSet = New DataSet

Dim dataTable As DataTable = New DataTable("table1")

dataTable.Columns.Add("col1", Type.GetType("System.String"))

dataSet.Tables.Add(dataTable)

Dim xmlData As String =

"<XmlDS><table1><col1>Value1</col1></table1><table1><col1>Value2</col1></table1></XmlDS>"

Dim xmlSR As System.IO.StringReader = New System.IO.StringReader(xmlData)

dataSet.ReadXml(xmlSR, XmlReadMode.IgnoreSchema)

C#

DataSet dataSet = new DataSet( );

DataTable dataTable = new DataTable("table1");

dataTable.Columns.Add("col1", typeof(string));

dataSet.Tables.Add(dataTable);

string xmlData =

"<XmlDS><table1><col1>Value1</col1></table1><table1><col1>Value2</col1></table1></XmlDS>";

Page 11: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-11-

System.IO.StringReader xmlSR = new System.IO.StringReader(xmlData);

dataSet.ReadXml(xmlSR, XmlReadMode.IgnoreSchema);

メモ:非常に大きなファイルを読み込む際に ReadXml を呼び出すと、パフォーマンスが低下する事が

有る。大きなファイルを読み込む場合に、ReadXml のパフォーマンスを最大にするには、DataSet の

テーブル毎に BeginLoadData メソッドを呼び出し、其の後で ReadXml を呼び出す。最後に、次の例

に示す様に、DataSet のテーブル毎に EndLoadData を呼び出す。

Visual Basic

Dim dataTable As DataTable

For Each dataTable In dataSet.Tables

dataTable.BeginLoadData( )

Next

dataSet.ReadXml("file.xml")

For Each dataTable in dataSet.Tables

dataTable.EndLoadData( )

Next

C#

foreach (DataTable dataTable in dataSet.Tables)

dataTable.BeginLoadData( );

dataSet.ReadXml("file.xml");

foreach (DataTable dataTable in dataSet.Tables)

dataTable.EndLoadData( );

メモ: DataSet の XSD スキーマに targetNamespace がインクルードされて居る場合、ReadXml を呼

び出して、名前空間が修飾されて居ない要素を含む XML を DataSet に読み込もうとすると、データが

読み取られず、例外が発生する事が有る。此の場合に、名前空間が指定されて居ない要素を読み込むに

は、XSD スキーマで elementFormDefault を qualified に設定する。次に例を示す。

<xsd:schema id="customDataSet"

elementFormDefault="qualified"

targetNamespace="http://www.tempuri.org/customDataSet.xsd"

xmlns="http://www.tempuri.org/customDataSet.xsd"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

</xsd:schema>

XML のデータの結合

既に、DataSet にデータが含まれて居る場合には、DataSet の既存のデータに XML の新しいデータが

追加される。ReadXml では、XML の中で主キーが一致する行情報を DataSet に結合しない。既存の行

情報を XML の新しい情報で上書きするには、ReadXml を使用して新しい DataSet を作成してから、

新しい DataSet を既存の DataSet へ結合する。XmlReadMode が DiffGram の ReadXML を使用して

DiffGram を読み込むと、同一の一意の識別子を持つ行が結合される。

Page 12: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-12-

■ XML データと仕ての DataSet の書き込み【此処から】

ADO.NET では、DataSet の XML 表現を記述する事が出来る。此の時、DataSet にスキーマが含まれ

ていても、含まれて居なくても構わない。XML にインラインで含まれて居るスキーマ情報は、XML ス

キーマ定義言語(XSD)を使用して記述されて居る。スキーマには、リレーション定義及び制約定義と、

DataSet のテーブル定義が含まれて居る。

DataSet が XML データと仕て書き込まれると、DataSet の行は現在のバージョンで書き込まれる。但

し、行の現在の値と元の値の両方を含めるには、DataSet を DiffGram と仕て書き込む。

DataSet の XML 表現は、ファイル、ストリーム、XmlWriter、又は文字列に書き込む事が出来る。複

数の書き込み先が有る事から、DataSet の XML 表現の転送方法を柔軟に変更出来る。DataSet の XML

表現を文字列と仕て取得するには、次の例に示す様に GetXml メソッドを使用する。

Visual Basic

Dim xmlDS As String = custDS.GetXml( )

C#

string xmlDS = custDS.GetXml( );

GetXml は、スキーマ情報が含まれて居ない DataSet の XML 表現を返す。DataSet (XML スキーマ) の

スキーマ情報を文字列に書き込むには、GetXmlSchema を使用する。

DataSet をファイル、ストリーム、又は XmlWriter に書き込むには、WriteXml メソッドを使用する。

WriteXml に渡す 1 番目のパラメータは、XML の出力先で有る。たとえば、ファイル名や

System.IO.TextWriter オブジェクト等が含まれて居る文字列を渡す。XmlWriteMode の 2 番目のパラ

メータは、XML 出力の書き込み方法を指定する。此のパラメータは省略出来る。

XmlWriteMode のオプションを次の表に示す。

XmlWriteMode の

オプション

説明

IgnoreSchema DataSetの現在の内容をXMLスキーマを含まないXMLデータと仕て書き込

む。此れは、既定の設定で有る。

WriteSchema DataSet の現在の内容を XML データと仕て書き込む。此の時、リレーショ

ナル構造がインライン XML スキーマと仕て書き込まれる。

DiffGram 元の値と現在の値を含め、DataSet 全体を DiffGram と仕て書き込む。詳細

に付いては、「DiffGram」を参照され度い。

DataRelation オブジェクトが格納されて居る DataSet の XML 表現を書き込む時には、多くの場合、

此の XML 表現で、それぞれの親子のリレーションを持つ子行が関連する親要素内に入れ子になる様に

する。此の様な入れ子の状態にするには、DataSet へ DataRelation を追加する時に、DataRelation の

Nested プロパティを true に設定する。詳細に付いては、「入れ子の DataRelation」を参照され度い。

DataSet の XML 表現をファイルに書き込む 2 つの例を次に示す。1 番目の例では、書き込まれる XML

のファイル名が文字列と仕て WriteXml へ渡される。2 番目の例では、System.IO.StreamWriter オブ

ジェクトが渡される。

Visual Basic

custDS.WriteXml("Customers.xml", XmlWriteMode.WriteSchema)

C#

custDS.WriteXml("Customers.xml", XmlWriteMode.WriteSchema);

Page 13: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-13-

Visual Basic

Dim xmlSW As System.IO.StreamWriter = New System.IO.StreamWriter("Customers.xml")

custDS.WriteXml(xmlSW, XmlWriteMode.WriteSchema)

xmlSW.Close( )

C#

System.IO.StreamWriter xmlSW = new System.IO.StreamWriter("Customers.xml");

custDS.WriteXml(xmlSW, XmlWriteMode.WriteSchema);

xmlSW.Close( );

XML 要素、属性、及びテキストへの列の割り当て

テーブルの列を XML 形式で表す方法を指定するには、DataColumn オブジェクトの ColumnMapping

プロパティを使用する。テーブル列の ColumnMapping プロパティの MappingType 値と、各値を適用

した結果の XML の一覧を次の表に示す。

MappingType

の値

説明

Element 此れは、既定の設定で有る。列が XML 要素と仕て書き込まれる。此の時、

ColumnName は要素名になり、列の内容は要素のテキストと仕て書き込まれる。次

に例を示す。

<ColumnName>Column Contents</ColumnName>

Attribute 列が、現在の行の XML 要素の XML 属性と仕て書き込まれる。此の時、

ColumnName は属性名になり、列の内容は属性の値と仕て書き込まれる。次に例を

示す。

<RowElement ColumnName="Column Contents" />

SimpleContent 列の内容が、現在の行の XML 要素のテキストと仕て書き込まれる。次に例を示す。

<RowElement>Column Contents</RowElement>

Element 列又は入れ子になったリレーションの有るテーブルの列に対しては、

SimpleContent を設定出来ない。

Hidden 列は XML 出力に書き込まれない。

■ XML の DataSet スキーマ情報の読み込み

DataSet のスキーマ (テーブル、列、リレーション、及び制約) は、プログラムを使用して定義され、

DataAdapter の Fill メソッド又は FillSchema メソッドに依って作成されるか、あるいは XML ドキュ

メントから読み込まれる。XML ドキュメントから DataSet スキーマ情報を読み込むには、DataSet の

ReadXmlSchema メソッド又は InferXmlSchema メソッドを使用する。ReadXmlSchema を使用する

と、XML スキーマ定義言語(XSD)スキーマが含まれて居るドキュメント又はインライン XML スキ

ーマが含まれて居る XML ドキュメントから、DataSet スキーマ情報を読み込むか又は推論出来る。

InferXmlSchema を使用すると、XML ドキュメントからスキーマを推論出来る。此の時、指定した特

定の XML 名前空間は無視される。

ReadXmlSchema

XML ドキュメントから DataSet のスキーマ丈を読み込み、データを読み込まない様にするには、

DataSetのReadXmlSchemaメソッドを使用する。ReadXmlSchemaは、XMLスキーマ定義言語(XSD)

スキーマを使用して定義されて居る DataSet を作成する。

ReadXmlSchema メソッドは、ファイル名、ストリーム、又は読み込む XML ドキュメントが格納され

て居る XmlReader の孰れか 1 つを引数と仕て受け取る。此の XML ドキュメントには、スキーマ丈が

含まれて居るか、又はデータの有る XML 要素と共にスキーマがインラインで含まれて居る。XML ス

キーマと仕てのインラインスキーマを書き込む方法の詳細に付いては、「XML スキーマ(XSD)からの

Page 14: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-14-

DataSet リレーショナル構造の生成」を参照され度い。

ReadXmlSchema に渡された XML ドキュメントに、インラインスキーマ情報が含まれて居ない場合、

ReadXmlSchema は XML ドキュメントの要素からスキーマを推論する。DataSet に既にスキーマが含

まれて居る場合には、現在のスキーマを拡張する為、新しい列が既存のテーブルに追加される。テーブ

ルが存在しない場合には、新しいテーブルが追加される。DataSet に既に追加される列が存在して居る

が、XML で検出された列の型と矛盾する場合には、例外がスローされる。ReadXmlSchema に依る XML

ドキュメントからのスキーマの推論方法の詳細に付いては、「XML からの DataSet リレーショナル構造

の推論」を参照され度い。

ReadXmlSchemaはDataSetスキーマの読み込み又は推論の孰れかを実行するが、DataSetのReadXml

メソッドは、スキーマと XML ドキュメントのデータの両方の読み込み又は推論を実行する。詳細に付

いては、「XML からの DataSet の読み込み」を参照され度い。

XMLドキュメント又はXMLストリームからDataSetスキーマを読み込む方法を次のコード例に示す。

1番目の例では、XMLスキーマ ファイル名がReadXmlSchemaメソッドへ渡される。2番目の例では、

System.IO.StreamReader が示されて居る。

Visual Basic

Dim dataSet As DataSet = New DataSet

dataSet.ReadXmlSchema("schema.xsd")

C#

DataSet dataSet = new DataSet( );

dataSet.ReadXmlSchema("schema.xsd");

Visual Basic

Dim xmlStream As System.IO.StreamReader = New System.IO.StreamReader ("schema.xsd");

Dim dataSet As DataSet = New DataSet

dataSet.ReadXmlSchema(xmlStream)

xmlStream.Close( )

C#

System.IO.StreamReader xmlStream = new System.IO.StreamReader("schema.xsd");

DataSet dataSet = new DataSet( );

dataSet.ReadXmlSchema(xmlStream);

xmlStream.Close( );

InferXmlSchema

DataSet に対し、DataSet の InferXmlSchema メソッドを使用して XML ドキュメントのスキーマを推

論する様に指示出来る。InferXmlSchema は、XmlReadMode を InferSchema に設定した ReadXml (デ

ータの読み込みとスキーマの推論) と、読み取られるドキュメントにインラインスキーマが含まれて居

ない場合の ReadXmlSchema の両方と同様の機能を備えて居る。但し InferXmlSchema には、スキー

マを推論する時に無視する特定の XML 名前空間を指定できる追加機能を用意して居る。

InferXmlSchema に必要な 2 つの引数は、XML ドキュメントの位置と、此の操作に依って無視される

XML 名前空間の文字列配列で有る。XML ドキュメントの位置は、ファイル名、ストリーム、又は

XmlReader に依って指定される。

たとえば、次の様な XML が有るとする。

<NewDataSet xmlns:od="urn:schemas-microsoft-com:officedata">

<Categories>

<CategoryID od:adotype="3">1</CategoryID>

Page 15: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-15-

<CategoryName od:maxLength="15" od:adotype="130">Beverages</CategoryName>

<Description od:adotype="203">Soft drinks and teas</Description>

</Categories>

<Products>

<ProductID od:adotype="20">1</ProductID>

<ReorderLevel od:adotype="3">10</ReorderLevel>

<Discontinued od:adotype="11">0</Discontinued>

</Products>

</NewDataSet>

前述の XML ドキュメントの要素に対して指定されて居る属性により、ReadXmlSchema メソッドと、

XmlReadMode が InferSchema に設定されて居る ReadXml メソッドは、孰れもドキュメントの総ての

要素 (Categories、CategoryID、CategoryName、Description、Products、ProductID、ReorderLevel、

及び Discontinued) に対してテーブルを作成する。詳細に付いては、「XML からの DataSet リレーシ

ョナル構造の推論」を参照され度い。但し、此の作成方法よりも適切な方法と仕ては、最初に Categories

テーブルとProducts テーブル丈を作成し、次にCategories テーブルのCategoryID、CategoryName、

及び Description 列を作成し、Products テーブルの ProductID、ReorderLevel 及び Discontinued 列

を作成する方法が有る。推論されたスキーマが、XML 要素に指定されて居る属性を無視する様にする

には、InferXmlSchema メソッドを使用して officedata の XML 名前空間を無視する様に指定する。此

の例を次に示す。

Visual Basic

Dim dataSet As DataSet = New DataSet

dataSet.InferXmlSchema("input_od.xml", New String[] {"urn:schemas-microsoft-com:officedata"})

C#

DataSet dataSet = new DataSet( );

dataSet.InferXmlSchema("input_od.xml", new string[] "urn:schemas-microsoft-com:officedata");

■ XML スキーマ(XSD)と仕ての DataSet スキーマ情報の書き込み

DataSet のスキーマを XML スキーマ定義言語(XSD)スキーマと仕て書き込むと、此のスキーマを

XML ドキュメントに転送出来る。此の時関連データを含む定義、又は関連データを含まない定義が出

来る。XML スキーマはファイル、ストリーム、XmlWriter、又は文字列に書き込む事ができる為、厳

密に型指定された DataSet を生成する時に役立ちます。厳密に型指定された DataSet オブジェクトの

詳細に付いては、「型指定された DataSet の使用」を参照され度い。

テーブルの列を XML スキーマで表す方法を指定するには、DataColumn オブジェクトの

ColumnMapping プロパティを使用する。詳細に付いては、「XML データと仕ての DataSet の書き込み」

の「XML 要素、属性、及びテキストへの列の割り当て」を参照され度い。

DataSet スキーマを XML スキーマと仕てファイル、ストリーム、又は XmlWriter に書き込むには、

DataSet の WriteXmlSchema メソッドを使用する。WriteXmlSchema は、XML スキーマの書き込み

先を指定するパラメータを 1 つ受け取る。ファイル名を含んだ文字列と StreamWriter オブジェクトを

渡して DataSet の XML スキーマをファイルに書き込む方法を示すコード例を次に示す。

Visual Basic

dataSet.WriteXmlSchema("Customers.xsd")

C#

dataSet.WriteXmlSchema("Customers.xsd");

Visual Basic

Page 16: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-16-

Dim writer As System.IO.StreamWriter = New System.IO.StreamWriter("Customers.xsd")

dataSet.WriteXmlSchema(writer)

writer.Close( )

C#

System.IO.StreamWriter writer = new System.IO.StreamWriter("Customers.xsd");

dataSet.WriteXmlSchema(writer);

writer.Close( );

DataSet のスキーマを取得し、XML スキーマ文字列と仕て書き込むには、次の例に示す様に

GetXmlSchema メソッドを使用する。

Visual Basic

Dim schemaString As String = dataSet.GetXmlSchema( )

C#

string schemaString = dataSet.GetXmlSchema( );

■ Dataset と XmlDataDocument の同期

ADO.NET の DataSet には、データのリレーショナル表現が有る。階層データにアクセスするに

は、.NET Framework で使用できる XML クラスを使用出来る。従来、此の 2 つのデータ表現は個別

に使用されていました。.NET Framework では、データのリレーショナル表現と階層表現の両方へリア

ルタイムに同期的な方法でアクセス出来る。リレーショナル表現にアクセスするには DataSet オブジェ

クトを使用する。階層表現にアクセスするには XmlDataDocument オブジェクトを使用する。

DataSetをXmlDataDocument と同期する時には、DataSet とXmlDataDocumentで1つのデータ セ

ットが使用される。つまり DataSet が変更されると、其の変更内容が XmlDataDocument に反映され

る。此の逆の反映も行われます。DataSet と XmlDataDocument の間のリレーションシップにより、1

つのアプリケーションから 1 つのデータ セットを使用して、DataSet の周囲に構築されたサービス ス

イート全体 (Web フォーム、Windows フォーム コントロール、Visual Studio、.NET デザイナ等) に

アクセスしたり、XML サービス スイート (XSL (Extensible Stylesheet Language)、XSLT (XSL

Transformations)、XPath (XML Path Language) 等) にアクセスしたりできる優れた柔軟性を実現す

る。アプリケーションでアクセス対象とするサービス セットを選択する必要は有りません。どちらの

サービス セットにもアクセス出来る。

DataSet を XmlDataDocument と同期する方法は数種類有る。次の操作を行う事が出来る。

・DataSet にスキーマ (リレーショナル構造 ) とデータを読み込み、此の DataSet を新しい

XmlDataDocument と同期する。此の方法では、既存のリレーショナルデータの階層ビューが作成

される。次に例を示す。

Visual Basic

Dim dataSet As DataSet = New DataSet

' Add code here to populate the DataSet with schema and data.

Dim xmlDoc As XmlDataDocument = New XmlDataDocument(dataSet)

C#

DataSet dataSet = new DataSet( );

// Add code here to populate the DataSet with schema and data.

XmlDataDocument xmlDoc = new XmlDataDocument(dataSet);

Page 17: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-17-

・DataSet にスキーマ丈を読み込み、此の DataSet (厳密に型指定された DataSet 等 ) を

XmlDataDocument と同期する。次に、XML ドキュメントから XmlDataDocument を読み込む。

此の方法では、既存の階層データのリレーショナル ビューが作成される。DataSet スキーマのテー

ブル名と列名が、同期をとる XML 要素の名前と一致して居る必要が有る。此の名前の一致では、大

文字と小文字が区別される。

DataSet のスキーマが一致する必要が有るのは、リレーショナル ビューで公開する XML 要素丈で

有る。つまり、此のドキュメント上に非常に大きい XML ドキュメントと非常に小さなリレーショナ

ル ウィンドウを作成出来る。DataSet が XML ドキュメントの一部丈を公開する場合でも、

XmlDataDocument は XML ドキュメント全体を保持する。此の説明に関する詳しい例に付いては、

「DataSet と XmlDataDocument の同期の例」を参照され度い。

DataSet を作成して其のスキーマを読み込み、XmlDataDocument と同期する手順を示すコード例

を次に示す。DataSet スキーマが一致する必要が有るのは、XmlDataDocument の中で DataSet を

使用して公開する要素丈で有る。

Visual Basic

Dim dataSet As DataSet = New DataSet

' Add code here to populate the DataSet with schema, but not data.

Dim xmlDoc As XmlDataDocument = New XmlDataDocument(dataSet)

xmlDoc.Load("XMLDocument.xml")

C#

DataSet dataSet = new DataSet( );

// Add code here to populate the DataSet with schema, but not data.

XmlDataDocument xmlDoc = new XmlDataDocument(dataSet);

xmlDoc.Load("XMLDocument.xml");

データが含まれて居る DataSet を XmlDataDocument と同期する場合には、XmlDataDocument を

読み込む事は出来ない。読み込もうとすると例外がスローされる。

・新しいXmlDataDocumentを作成して、XMLドキュメントから此のXmlDataDocumentを読み込む。

次に、XmlDataDocument の DataSet プロパティを使用してデータのリレーショナル ビューにアク

セスする。DataSet を使用して XmlDataDocument のデータを表示するには、DataSet スキーマを

設定する必要が有る。此の場合も、DataSet スキーマのテーブル名と列名が、同期をとる XML 要素

の名前と一致して居る必要が有る。此の名前の一致では、大文字と小文字が区別される。

XmlDataDocument のデータのリレーショナル ビューにアクセスする方法を次のコード例に示す。

Visual Basic

Dim xmlDoc As XmlDataDocument = New XmlDataDocument

Dim dataSet As DataSet = xmlDoc.DataSet

' Add code here to create the schema of the DataSet to view the data.

xmlDoc.Load("XMLDocument.xml")

C#

XmlDataDocument xmlDoc = new XmlDataDocument( );

DataSet dataSet = xmlDoc.DataSet;

Page 18: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-18-

// Add code here to create the schema of the DataSet to view the data.

xmlDoc.Load("XMLDocument.xml");

DataSet を XmlDataDocument と同期するもう 1 つの利点は、XML ドキュメントが完全に保持され

る事で有る。ReadXml を使用して XML ドキュメントのデータを DataSet に格納すると、WriteXml

を使用してデータが XML ドキュメントと仕て書き込まれる時に、此の XML ドキュメントと元の XML

ドキュメントが大幅に異なる場合が有る。此れは、DataSet では XML ドキュメントから読み込んだ空

白等の書式設定や、要素順序等の階層情報が維持されない為で有る。DataSet には、XML ドキュメン

トで無視された要素も含まれて居ない。此れは、此れらの要素が Dataset のスキーマに一致しない為で

有る。XmlDataDocument を DataSet と同期する事で、元の XML ドキュメントの書式設定要素や階

層要素の構造が XmlDataDocument で維持され、DataSet には DataSet に適切なデータ及びスキーマ

情報丈が含まれる。

DataSet を XmlDataDocument と同期する場合、DataRelation オブジェクトが入れ子か何うかに依っ

て同期結果が異なります。詳細に付いては、「入れ子の DataRelation」を参照され度い。

DataSet と XmlDataDocument の同期の例

此のセクションでは、XmlDataDocument と同期され、厳密に型指定された DataSet を使用して、注

文書を処理する手順の 1 ステップを例に説明する。此の例では、DataSet をソース XML ドキュメン

トの一部丈と一致する最小限のスキーマと共に作成する。此の例では、XmlDataDocument を使用して

ソース XML ドキュメントが完全に保持される為、XML ドキュメントのサブセットを公開する時に

DataSet を使用出来る。

注文書に関する情報 (顧客情報、発注品目、出荷情報等) を総て含む XML ドキュメントの例を次に示

す。

<?xml version="1.0" standalone="yes"?>

<PurchaseOrder>

<Customers>

<CustomerID>CHOPS</CustomerID>

<Orders>

<OrderID>10966</OrderID>

<OrderDetails>

<OrderID>10966</OrderID>

<ProductID>37</ProductID>

<UnitPrice>26</UnitPrice>

<Quantity>8</Quantity>

<Discount>0</Discount>

</OrderDetails>

<OrderDetails>

<OrderID>10966</OrderID>

<ProductID>56</ProductID>

<UnitPrice>38</UnitPrice>

<Quantity>12</Quantity>

<Discount>0.15</Discount>

</OrderDetails>

<OrderDetails>

<OrderID>10966</OrderID>

<ProductID>62</ProductID>

Page 19: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-19-

<UnitPrice>49.3</UnitPrice>

<Quantity>12</Quantity>

<Discount>0.15</Discount>

</OrderDetails>

<CustomerID>CHOPS</CustomerID>

<EmployeeID>4</EmployeeID>

<OrderDate>1998-03-20T00:00:00.0000000</OrderDate>

<RequiredDate>1998-04-17T00:00:00.0000000</RequiredDate>

<ShippedDate>1998-04-08T00:00:00.0000000</ShippedDate>

<ShipVia>1</ShipVia>

<Freight>27.19</Freight>

<ShipName>Chop-suey Chinese</ShipName>

<ShipAddress>Hauptstr. 31</ShipAddress>

<ShipCity>Bern</ShipCity>

<ShipPostalCode>3012</ShipPostalCode>

<ShipCountry>Switzerland</ShipCountry>

</Orders>

<CompanyName>Chop-suey Chinese</CompanyName>

<ContactName>Yang Wang</ContactName>

<ContactTitle>Owner</ContactTitle>

<Address>Hauptstr. 29</Address>

<City>Bern</City>

<PostalCode>3012</PostalCode>

<Country>Switzerland</Country>

<Phone>0452-076545</Phone>

</Customers>

<Shippers>

<ShipperID>1</ShipperID>

<CompanyName>Speedy Express</CompanyName>

<Phone>(503) 555-0100</Phone>

</Shippers>

<Shippers>

<ShipperID>2</ShipperID>

<CompanyName>United Package</CompanyName>

<Phone>(503) 555-0101</Phone>

</Shippers>

<Shippers>

<ShipperID>3</ShipperID>

<CompanyName>Federal Shipping</CompanyName>

<Phone>(503) 555-0102</Phone>

</Shippers>

<Products>

<ProductID>37</ProductID>

<ProductName>Gravad lax</ProductName>

<QuantityPerUnit>12 - 500 g pkgs.</QuantityPerUnit>

<UnitsInStock>11</UnitsInStock>

<UnitsOnOrder>50</UnitsOnOrder>

<ReorderLevel>25</ReorderLevel>

</Products>

<Products>

<ProductID>56</ProductID>

Page 20: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-20-

<ProductName>Gnocchi di nonna Alice</ProductName>

<QuantityPerUnit>24 - 250 g pkgs.</QuantityPerUnit>

<UnitsInStock>21</UnitsInStock>

<UnitsOnOrder>10</UnitsOnOrder>

<ReorderLevel>30</ReorderLevel>

</Products>

<Products>

<ProductID>62</ProductID>

<ProductName>Tarte au sucre</ProductName>

<QuantityPerUnit>48 pies</QuantityPerUnit>

<UnitsInStock>17</UnitsInStock>

<UnitsOnOrder>0</UnitsOnOrder>

<ReorderLevel>0</ReorderLevel>

</Products>

</PurchaseOrder>

前述の XML ドキュメントに含まれて居る注文書の情報を処理する手順の 1 ステップと仕て、企業の現

在の在庫のデータを使用して此の注文書が処理される。企業の倉庫で注文を処理する従業員は、注文書

の内容を総て確認する必要は有りません。確認する必要が有る情報は、注文書の製品情報丈で有る。XML

ドキュメントの製品情報丈を公開するには、厳密に型指定した DataSet を作成し、XML スキーマ定義

言語(XSD)スキーマと仕て記述されて居るスキーマを此の DataSet に読み込む。此のスキーマは、

注文の製品と数量に対応して居る。厳密に型指定された DataSet オブジェクトの詳細に付いては、「型

指定された DataSet の使用」を参照され度い。

此のサンプルの厳密に型指定された DataSet の生成元となるスキーマを次のコードに示す。

<?xml version="1.0" standalone="yes"?>

<xs:schema id="OrderDetail" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="OrderDetail" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="OrderDetails" codegen:typedName="LineItem"

codegen:typedPlural="LineItems">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderID" type="xs:int" minOccurs="0"

codegen:typedName="OrderID"/>

<xs:element name="Quantity" type="xs:short" minOccurs="0"

codegen:typedName="Quantity"/>

<xs:element name="ProductID" type="xs:int" minOccurs="0"

codegen:typedName="ProductID"/>

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="Products" codegen:typedName="Product"

codegen:typedPlural="Products">

<xs:complexType>

<xs:sequence>

Page 21: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-21-

<xs:element name="ProductID" type="xs:int" minOccurs="0"

codegen:typedName="ProductID"/>

<xs:element name="ProductName" type="xs:string" minOccurs="0"

codegen:typedName="ProductName"/>

<xs:element name="QuantityPerUnit" type="xs:string" minOccurs="0"

codegen:typedName="QuantityPerUnit"/>

<xs:element name="UnitsInStock" type="xs:short" minOccurs="0"

codegen:typedName="UnitsInStock"/>

<xs:element name="UnitsOnOrder" type="xs:short" minOccurs="0"

codegen:typedName="UnitsOnOrder"/>

<xs:element name="ReorderLevel" type="xs:short" minOccurs="0"

codegen:typedName="ReorderLevel"/>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

<xs:unique name="Constraint1">

<xs:selector xpath=".//Products" />

<xs:field xpath="ProductID" />

</xs:unique>

<xs:keyref name="Relation1" refer="Constraint1" codegen:typedChildren="GetLineItems"

codegen:typedParent="Product">

<xs:selector xpath=".//OrderDetails" />

<xs:field xpath="ProductID" />

</xs:keyref>

</xs:element>

</xs:schema>

元の XML ドキュメントの OrderDetails 要素と Products 要素の情報丈が DataSet のスキーマにイン

クルードされる。DataSet を XmlDataDocument と同期させる事で、DataSet にインクルードされて

居ない要素も XML ドキュメントに保持される。

Northwind.FillOrder の名前空間を使用して XML スキーマから生成される、厳密に型指定された

DataSet を使用すると、元の XML ドキュメントの一部を公開出来る。XML ドキュメントの一部を公

開するには、ソース XML ドキュメントから読み込まれた XmlDataDocument に DataSet を同期させ

ます。此のスキーマから生成された DataSet には構造が含まれて居るが、データは含まれて居ない。

XML を XmlDataDocument に読み込むと、データが格納される。データが既に含まれて居る DataSet

と同期された XmlDataDocument を読み込もうとすると、例外がスローされる。

DataSet と XmlDataDocument の更新後には、XmlDataDocument に依って、変更後の XML ドキュ

メントと、DataSet に依って無視された要素を出力出来る。此の例を次に示す。注文書の処理手順では、

注文品目の入力後に、変更された XML ドキュメントが注文処理の次のステップ (社内の出荷部門) に

渡される。

Visual Basic

Imports System

Imports System.Data

Imports System.Xml

Imports Northwind.FillOrder

Public class Sample

Page 22: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-22-

Public Shared Sub Main( )

Dim orderDS As OrderDetail = New OrderDetail

Dim xmlDocument As XmlDataDocument = New XmlDataDocument(orderDS)

xmlDocument.Load("Order.xml")

Dim orderItem As OrderDetail.LineItem

Dim product As OrderDetail.Product

For Each orderItem In orderDS.LineItems

product = orderItem.Product

' Remove quantity from the current stock.

product.UnitsInStock = CType(product.UnitsInStock - orderItem.Quantity, Short)

' If the remaining stock is less than the reorder level, order more.

If ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel) Then

product.UnitsOnOrder = CType(product.UnitsOnOrder + product.ReorderLevel, Short)

End If

Next

xmlDocument.Save("Order_out.xml")

End Sub

End Class

C#

using System;

using System.Data;

using System.Xml;

using Northwind.FillOrder;

public class Sample

{

public static void Main( )

{

OrderDetail orderDS = new OrderDetail( );

XmlDataDocument xmlDocument = new XmlDataDocument(orderDS);

xmlDocument.Load("Order.xml");

foreach (OrderDetail.LineItem orderItem in orderDS.LineItems)

{

OrderDetail.Product product = orderItem.Product;

// Remove quantity from the current stock.

product.UnitsInStock = (short)(product.UnitsInStock - orderItem.Quantity);

// If the remaining stock is less than the reorder level, order more.

if ((product.UnitsInStock + product.UnitsOnOrder) < product.ReorderLevel)

product.UnitsOnOrder = (short)(product.UnitsOnOrder + product.ReorderLevel);

}

xmlDocument.Save("Order_out.xml");

Page 23: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-23-

}

}

DataSet に対する XPath クエリの実行

同期されたDataSet とXmlDataDocument との間のリレーションシップに依って、XPath (XML Path

Language) クエリ等の XML サービスが使用出来る。XML サービスは XmlDataDocument にアクセ

スし、DataSet に直接アクセスするよりも、特定の機能を効率的に実行出来る。たとえば、DataTable

の Select メソッドを使用して DataSet の他のテーブルとのリレーションシップをナビゲートする代わ

りに、DataSet と同期化された XmlDataDocument に対して XPath クエリを実行すると、

XmlNodeList 形式で XML 要素のリストを取得出来る。XmlElement ノードと仕てキャストされた

XmlNodeList のノードを XmlDataDocument の GetRowFromElement メソッドに渡すと、同期化さ

れた DataSet のテーブルの行に一致する DataRow 参照が返される。

たとえば、次に示すコード例では孫 XPath クエリが実行される。DataSet には、Customers、Orders、

及び OrderDetails の 3 つのテーブルが格納されて居る。此のサンプルでは、Customers テーブルと

Orders テーブルの間に親子のリレーションが作成され、次に Orders テーブルと OrderDetails テー

ブルの間に親子のリレーションが作成される。XPath クエリが実行され、値 43 の ProductID ノード

を持つ孫 OrderDetails ノードの有る Customers ノードの XmlNodeList リストが返される。つまり、

此のサンプルでは、XPath クエリを使用して ProductID が 43 の製品を注文した顧客を確認する。

Visual Basic

' Assumes that connection is a valid SqlConnection.

connection.Open( )

Dim dataSet As DataSet = New DataSet("CustomerOrders")

Dim customerAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT * FROM Customers", connection)

customerAdapter.Fill(dataSet, "Customers")

Dim orderAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT * FROM Orders", connection)

orderAdapter.Fill(dataSet, "Orders")

Dim detailAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT * FROM [Order Details]", connection)

detailAdapter.Fill(dataSet, "OrderDetails")

connection.Close( )

dataSet.Relations.Add("CustOrders", _

dataSet.Tables("Customers").Columns("CustomerID"), _

dataSet.Tables("Orders").Columns("CustomerID")).Nested = true

dataSet.Relations.Add("OrderDetail", _

dataSet.Tables("Orders").Columns("OrderID"), _

dataSet.Tables("OrderDetails").Columns("OrderID"), false).Nested = true

Dim xmlDoc As XmlDataDocument = New XmlDataDocument(dataSet)

Dim nodeList As XmlNodeList = xmlDoc.DocumentElement.SelectNodes( _

"descendant::Customers[*/OrderDetails/ProductID=43]")

Dim dataRow As DataRow

Dim xmlNode As XmlNode

Page 24: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-24-

For Each xmlNode In nodeList

dataRow = xmlDoc.GetRowFromElement(CType(xmlNode, XmlElement))

If Not dataRow Is Nothing then Console.WriteLine(xmlRow(0).ToString( ))

Next

C#

// Assumes that connection is a valid SqlConnection.

connection.Open( );

DataSet dataSet = new DataSet("CustomerOrders");

SqlDataAdapter customerAdapter = new SqlDataAdapter(

"SELECT * FROM Customers", connection);

customerAdapter.Fill(dataSet, "Customers");

SqlDataAdapter orderAdapter = new SqlDataAdapter(

"SELECT * FROM Orders", connection);

orderAdapter.Fill(dataSet, "Orders");

SqlDataAdapter detailAdapter = new SqlDataAdapter(

"SELECT * FROM [Order Details]", connection);

detailAdapter.Fill(dataSet, "OrderDetails");

connection.Close( );

dataSet.Relations.Add("CustOrders",

dataSet.Tables["Customers"].Columns["CustomerID"],

dataSet.Tables["Orders"].Columns["CustomerID"]).Nested = true;

dataSet.Relations.Add("OrderDetail",

dataSet.Tables["Orders"].Columns["OrderID"],

dataSet.Tables["OrderDetails"].Columns["OrderID"],

false).Nested = true;

XmlDataDocument xmlDoc = new XmlDataDocument(dataSet);

XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes(

"descendant::Customers[*/OrderDetails/ProductID=43]");

DataRow dataRow;

foreach (XmlNode xmlNode in nodeList)

{

dataRow = xmlDoc.GetRowFromElement((XmlElement)xmlNode);

if (dataRow != null)

Console.WriteLine(dataRow[0]);

}

DataSet への XSLT 変換の適用

DataSet の WriteXml メソッドを使用すると、DataSet の内容を XML データと仕て書き込む事が出来

る。一般的な作業は、XSLT (XML Transformation) を使用して此の XML を別の形式へ変換する操作

で有る。但し DataSet を XmlDataDocument と同期する事で、最初に WriteXml を使用して DataSet

の内容を XML データと仕て書き込む操作を実行せずに、DataSet の内容に XSLT スタイルシートを適

Page 25: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-25-

用出来る。

DataSet にテーブルとリレーションシップを格納し、DataSet を XmlDataDocument と同期し、XSLT

スタイルシートを使用して DataSet の一部を HTML ファイルと仕て書き込む例を次に示す。次のコー

ドは、XSLT スタイルシートの内容で有る。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="CustomerOrders">

<HTML>

<STYLE>

BODY {font-family:verdana;font-size:9pt}

TD {font-size:8pt}

</STYLE>

<BODY>

<TABLE BORDER="1">

<xsl:apply-templates select="Customers"/>

</TABLE>

</BODY>

</HTML>

</xsl:template>

<xsl:template match="Customers">

<TR><TD>

<xsl:value-of select="ContactName"/>, <xsl:value-of select="Phone"/><BR/>

</TD></TR>

<xsl:apply-templates select="Orders"/>

</xsl:template>

<xsl:template match="Orders">

<TABLE BORDER="1">

<TR><TD valign="top"><B>Order:</B></TD><TD valign="top"><xsl:value-of

select="OrderID"/></TD></TR>

<TR><TD valign="top"><B>Date:</B></TD><TD valign="top"><xsl:value-of

select="OrderDate"/></TD></TR>

<TR><TD valign="top"><B>Ship To:</B></TD>

<TD valign="top"><xsl:value-of select="ShipName"/><BR/>

<xsl:value-of select="ShipAddress"/><BR/>

<xsl:value-of select="ShipCity"/>, <xsl:value-of select="ShipRegion"/> <xsl:value-of

select="ShipPostalCode"/><BR/>

<xsl:value-of select="ShipCountry"/></TD></TR>

</TABLE>

</xsl:template>

</xsl:stylesheet>

次のコードは、DataSet にデータを格納し、XSLT スタイル シートを適用する。

メモ:リレーションシップが含まれて居る DataSet にスタイル シートを適用する場合は、入れ子にな

って居るリレーションシップ毎に DataRelation の Nested プロパティを true に設定すると、パフォ

ーマンスが最大になります。此れにより、階層を自然な順番で上から下へと進みながらデータを変換す

る XSLT スタイル シートを利用できる様になります。パフォーマンスに大きく影響する XPath ロケ

Page 26: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-26-

ーション軸 (たとえば、スタイル シートのノード テスト式での preceding-sibling や

following-sibling) を使用して階層をたどる必要はなくなります。入れ子になったリレーションの詳細

に付いては、「入れ子の DataRelation」を参照され度い。

Visual Basic

' Assumes connection is a valid SqlConnection.

Dim dataSet As DataSet = New DataSet("CustomerOrders")

Dim customerAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT * FROM Customers", connection)

customerAdapter.Fill(dataSet, "Customers")

Dim orderAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT * FROM Orders", connection)

orderAdapter.Fill(dataSet, "Orders")

connection.Close( )

dataSet.Relations.Add("CustOrders", _

dataSet.Tables("Customers").Columns("CustomerID"), _

dataSet.Tables("Orders").Columns("CustomerID")).Nested = true

Dim xmlDoc As XmlDataDocument = New XmlDataDocument(dataSet)

Dim xslTran As XslTransform = New XslTransform

xslTran.Load("transform.xsl")

Dim writer As XmlTextWriter = New XmlTextWriter( _

"xslt_output.html", System.Text.Encoding.UTF8)

xslTran.Transform(xmlDoc, Nothing, writer)

writer.Close( )

C#

// Assumes connection is a valid SqlConnection.

connection.Open( );

DataSet custDS = new DataSet("CustomerDataSet");

SqlDataAdapter customerAdapter = new SqlDataAdapter(

"SELECT * FROM Customers", connection);

customerAdapter.Fill(custDS, "Customers");

SqlDataAdapter orderAdapter = new SqlDataAdapter(

"SELECT * FROM Orders", connection);

orderAdapter.Fill(custDS, "Orders");

connection.Close( );

custDS.Relations.Add("CustOrders",

custDS.Tables["Customers"].Columns["CustomerID"],

custDS.Tables["Orders"].Columns["CustomerID"]).Nested = true;

XmlDataDocument xmlDoc = new XmlDataDocument(custDS);

XslTransform xslTran = new XslTransform( );

Page 27: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-27-

xslTran.Load("transform.xsl");

XmlTextWriter writer = new XmlTextWriter("xslt_output.html",

System.Text.Encoding.UTF8);

xslTran.Transform(xmlDoc, null, writer);

writer.Close( );

■ 入れ子の DataRelation

データのリレーショナル表現では、各テーブルに含まれて居る行が、列又は列セットを使用して相互に

関連付けられて居る。ADO.NET の DataSet では、テーブル間のリレーションシップは DataRelation

を使用して実装される。DataRelation を作成すると、親子の列のリレーションシップは此のリレーシ

ョン丈をとおして管理される。テーブルと列はそれぞれ別個のエンティティで有る。XML のデータ階

層表現では、子要素が入れ子の状態で含まれて居る親要素に依って親子のリレーションシップが表現さ

れる。

子オブジェクトの入れ子を実現する為、DataSet が XmlDataDocument と同期されるか、又は

WriteXml を使用して XML データと仕て書き込まれる時に、DataRelation が Nested プロパティを公

開する。DataRelation の Nested プロパティを true に設定すると、XML データと仕て書き込まれる

時、又は XmlDataDocument と同期される時に、此のリレーションにおける子の行が親の列の中で入

れ子になります。DataRelation の Nested プロパティは既定では false に設定されて居る。

たとえば、次の様な DataSet が有るとする。

Visual Basic

' Assumes connection is a valid SqlConnection.

Dim customerAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT CustomerID, CompanyName FROM Customers", connection)

Dim orderAdapter As SqlDataAdapter = New SqlDataAdapter( _

"SELECT OrderID, CustomerID, OrderDate FROM Orders", connection)

connection.Open( )

Dim dataSet As DataSet = New DataSet("CustomerOrders")

customerAdapter.Fill(dataSet, "Customers")

orderAdapter.Fill(dataSet, "Orders")

connection.Close( )

Dim customerOrders As DataRelation = dataSet.Relations.Add( _

"CustOrders", dataSet.Tables("Customers").Columns("CustomerID"), _

dataSet.Tables("Orders").Columns("CustomerID"))

C#

// Assumes connection is a valid SqlConnection.

SqlDataAdapter customerAdapter = new SqlDataAdapter(

"SELECT CustomerID, CompanyName FROM Customers", connection);

SqlDataAdapter orderAdapter = new SqlDataAdapter(

"SELECT OrderID, CustomerID, OrderDate FROM Orders", connection);

connection.Open( );

DataSet dataSet = new DataSet("CustomerOrders");

customerAdapter.Fill(dataSet, "Customers");

Page 28: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-28-

orderAdapter.Fill(dataSet, "Orders");

connection.Close( );

DataRelation customerOrders = dataSet.Relations.Add(

"CustOrders", dataSet.Tables["Customers"].Columns["CustomerID"],

dataSet.Tables["Orders"].Columns["CustomerID"]);

此の DataSet では DataRelation オブジェクトの Nested プロパティが true に設定されて居ない為、

DataSet が XML データと仕て表される時に、子オブジェクトは親要素の中で入れ子になりません。

DataSet に対して WriteXml を呼び出した結果を次のコード例に示す。

<CustomerOrders>

<Customers>

<CustomerID>ALFKI</CustomerID>

<CompanyName>Alfreds Futterkiste</CompanyName>

</Customers>

<Customers>

<CustomerID>ANATR</CustomerID>

<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>

</Customers>

<Orders>

<OrderID>10643</OrderID>

<CustomerID>ALFKI</CustomerID>

<OrderDate>1997-08-25T00:00:00</OrderDate>

</Orders>

<Orders>

<OrderID>10692</OrderID>

<CustomerID>ALFKI</CustomerID>

<OrderDate>1997-10-03T00:00:00</OrderDate>

</Orders>

<Orders>

<OrderID>10308</OrderID>

<CustomerID>ANATR</CustomerID>

<OrderDate>1996-09-18T00:00:00</OrderDate>

</Orders>

</CustomerOrders>

Customers 要素と Orders 要素が兄弟要素と仕て示されて居る。Orders 要素を該当する親要素の子と

仕て表すには、DataRelation の Nested プロパティを true に設定し、次のコードを追加する必要が有

る。

Visual Basic

customerOrders.Nested = True

C#

customerOrders.Nested = true;

上記のコードを追加した結果の出力を次のコードに示す。此の例では、Orders 要素がそれぞれ該当す

る親要素の中で入れ子になって居る。

Page 29: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-29-

<CustomerOrders>

<Customers>

<CustomerID>ALFKI</CustomerID>

<Orders>

<OrderID>10643</OrderID>

<CustomerID>ALFKI</CustomerID>

<OrderDate>1997-08-25T00:00:00</OrderDate>

</Orders>

<Orders>

<OrderID>10692</OrderID>

<CustomerID>ALFKI</CustomerID>

<OrderDate>1997-10-03T00:00:00</OrderDate>

</Orders>

<CompanyName>Alfreds Futterkiste</CompanyName>

</Customers>

<Customers>

<CustomerID>ANATR</CustomerID>

<Orders>

<OrderID>10308</OrderID>

<CustomerID>ANATR</CustomerID>

<OrderDate>1996-09-18T00:00:00</OrderDate>

</Orders>

<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>

</Customers>

</CustomerOrders>

■ XML スキーマ(XSD)からの DataSet リレーショナル構造の生成

ここでは、XML スキーマ定義言語(XSD)スキーマ ドキュメントから DataSet のリレーショナルス

キーマを生成する方法に付いての概要を説明する。一般的には、スキーマの要素の各 complexType 子

要素に対して、テーブルが DataSet に生成される。テーブル構造は、複合型の定義に基づいて決定され

る。テーブルは、スキーマのトップレベル要素の DataSet に作成される。但し、complexType 要素が

別の complexType 要素内で入れ子になって居る場合、テーブルはトップレベルの complexType 要素に

丈作成される。其の場合、入れ子になった complexType 要素は、DataSet 内の DataTable に割り当て

られます。

XSD の詳細に付いては、World Wide Web Consortium (W3C) の Web サイト http://www.w3.org/ (英

語) に有る『XML Schema Part 0: Primer Recommendation』、『XML Schema Part 1: Structures

Recommendation』、及び『XML Schema Part 2: Datatypes Recommendation』を参照され度い。

customers 要素が MyDataSet 要素の子要素で有る XML スキーマの例を次に示す。此の MyDataSet

要素が DataSet 要素に該当する。

<xs:schema id="SomeID"

xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="customers" >

Page 30: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-30-

<xs:complexType >

<xs:sequence>

<xs:element name="CustomerID" type="xs:integer"

minOccurs="0" />

<xs:element name="CompanyName" type="xs:string"

minOccurs="0" />

<xs:element name="Phone" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

上記の例では、customers 要素は複合型の要素で有る。したがって、複合型の定義が解析され、割り当

て処理に依って次のテーブルが作成される。

Customers (CustomerID , CompanyName, Phone)

テーブルの各列のデータ型は、其れに対応する指定された要素又は属性の XML スキーマ型から派生す

る。

メモ: customers 要素が integer の様な単純な XML スキーマ データ型で有る場合、テーブルは生成

されません。テーブルが作成されるのは、複合型のトップレベル要素に対して丈で有る。

Schema 要素に InStateCustomers と OutOfStateCustomers の 2 つの子要素を持つ XML スキーマ

の例を次に示す。

<xs:schema id="SomeID"

xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="InStateCustomers" type="customerType" />

<xs:element name="OutOfStateCustomers" type="customerType" />

<xs:complexType name="customerType" >

</xs:complexType>

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element ref="customers" />

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

InStateCustomers とOutOfStateCustomersの2 つの子要素は、複合型の要素です (customerType)。

したがって、割り当て処理に依って DataSet に次の 2 つの同じテーブルが生成される。

InStateCustomers (CustomerID , CompanyName, Phone)

Page 31: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-31-

OutOfStateCustomers (CustomerID , CompanyName, Phone)

XML スキーマ(XSD)制約の DataSet 制約への割り当て

XML スキーマ定義言語(XSD)を使用すると、定義する要素と属性で制約を指定出来る。XML スキー

マを DataSet のリレーショナルスキーマに割り当てると、XML スキーマの制約が DataSet 内のテー

ブルと列の適切なリレーショナル制約に割り当てられます。

此のセクションでは、次の XML スキーマの制約の割り当てに付いて説明する。

・unique 要素を使用して指定される UNIQUE 制約

・key 要素を使用して指定されるキー制約

・keyref 要素を使用して指定されるキー参照制約

要素又は属性に対して制約を指定する事により、同じスキーマに基づくあらゆるドキュメントで、其の

要素の値に付いて特定の制限を適用出来る。たとえば、スキーマに有る Customer 要素の CustomerID

子要素のキー制約は、CustomerID 子要素の値が総てのドキュメントのインスタンスで一意で有り、

null 値が許可されない事を示す。

さらに、ドキュメント内のリレーションシップを確立する為に、ドキュメント内の要素及び属性間に制

約を指定する事も出来る。ドキュメント内で制約を指定する為にスキーマ内で key 制約又は keyref 制

約を使用すると、ドキュメントの要素と属性間にリレーションシップを持つ事になります。

割り当て処理は、此れらのスキーマ制約を DataSet 内に作成されたテーブルでの適切な制約に変換す

る。

・XML スキーマ(XSD)の UNIQUE 制約の DataSet 制約への割り当て

XML スキーマ定義言語(XSD)スキーマでは、unique 要素を使用して要素又は属性の UNIQUE 制約

を指定する。XML スキーマをリレーショナルスキーマに変換する処理では、XML スキーマの要素又は

属性で指定した UNIQUE 制約が、生成される DataSet に対応する DataTable の UNIQUE 制約に割

り当てられます。

unique 要素で指定できる msdata 属性を次の表に示す。

属性名 説明

msdata:ConstraintName 此の属性を指定した場合、其の値が制約名と仕て使用される。其れ以外の

場合は、name 属性に依って制約名の値が設定される。

msdata:PrimaryKey unique 要素に PrimaryKey="true" が有る場合、UNIQUE 制約は、

IsPrimaryKey プロパティが true に設定された状態で作成される。

unique 要素を使用して UNIQUE 制約を指定する XML スキーマの例を次に示す。

<xs:schema id="SampleDataSet"

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="Customers">

<xs:complexType>

<xs:sequence>

<xs:element name="CustomerID" type="xs:integer" minOccurs="0" />

<xs:element name="CompanyName" type="xs:string" minOccurs="0" />

<xs:element name="Phone" type="xs:string" />

Page 32: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-32-

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="SampleDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element ref="Customers" />

</xs:choice>

</xs:complexType>

<xs:unique

msdata:ConstraintName="UCustID"

name="UniqueCustIDConstr" >

<xs:selector xpath=".//Customers" />

<xs:field xpath="CustomerID" />

</xs:unique>

</xs:element>

</xs:schema>

スキーマの unique 要素を使用して、ドキュメント インスタンスの総ての Customers 要素に unique

要素を指定する。CustomerID 子要素の値は一意になる必要が有る。DataSet を作成する場合は、割り

当て処理に依ってスキーマが読み込まれ、次のテーブルが生成される。

Customers (CustomerID, CompanyName, Phone)

亦、次の DataSet に示す様に、割り当て処理に依って CustomerID 列に UNIQUE 制約を作成する事

も出来る(わかりやすい様に、関連するプロパティ丈を示す)。

DataSetName: MyDataSet

TableName: Customers

ColumnName: CustomerID

AllowDBNull: True

Unique: True

ConstraintName: UcustID

Type: UniqueConstraint

Table: Customers

Columns: CustomerID

IsPrimaryKey: False

生成される DataSet は UNIQUE 制約の為に IsPrimaryKey プロパティが False に設定される。列の

unique プロパティは、CustomerID 列の値が一意で有る事を示す (但し、列の AllowDBNull プロパ

ティで指定されて居る様に、CustomerID の値は null 参照となります)。

スキーマを変更し、オプションの msdata:PrimaryKey 属性を True に設定すると、UNIQUE 制約が

テーブルに作成される。AllowDBNull 列のプロパティが False に、制約の IsPrimaryKey プロパティ

が True に設定されると、CustomerID 列が主キー列になります。

XML スキーマの要素や属性を組み合わせて UNIQUE 制約を指定出来る。スキーマに別の xs:field 要

素を追加する事により、CustomerID の値と CompanyName の値の組み合わせを任意のインスタンス

の総ての Customers に対して必ず一意になる様に指定する方法を次の例で示す。

<xs:unique msdata:ConstraintName="SomeName" name="UniqueCustIDConstr" >

Page 33: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-33-

<xs:selector xpath=".//Customers" />

<xs:field xpath="CustomerID" />

<xs:field xpath="CompanyName" />

</xs:unique>

其の結果、DataSet に作成される制約を次に示す。

ConstraintName: SomeName

Table: Customers

Columns: CustomerID CompanyName

IsPrimaryKey: False

・XML スキーマ(XSD)のキー制約の DataSet 制約への割り当て

スキーマでは、key 要素を使用して要素又は属性のキー制約を指定出来る。キー制約を指定する要素又

は属性の値は、スキーマ インスタンス内で一意になる必要が有る。亦、null 値にする事は出来ない。

キー制約を定義する列の値を null 値にできない点を除くと、キー制約は UNIQUE 制約と同じで有る。

key 要素に指定できる msdata 属性を次の表に示す。

属性名 説明

msdata:ConstraintName 此の属性を指定した場合、其の値が制約名と仕て使用される。其れ以外の

場合は、name 属性に依って制約名の値が設定される。

msdata:PrimaryKey PrimaryKey="true" が指定されて居る場合、IsPrimaryKey 制約のプロ

パティを true に設定する事に依って、主キーになります。主キーの値は

null 値にできない為、AllowDBNull 列のプロパティが false に設定され

る。

キー制約を指定するスキーマの変換では、割り当て処理により、制約の列毎に AllowDBNull 列のプロ

パティが false に設定された状態でテーブルに UNIQUE 制約が作成される。key 要素で

msdata:PrimaryKey="true" を指定しない限り、UNIQUE 制約の IsPrimaryKey プロパティも false

に設定される。此れは、スキーマに PrimaryKey="true" が指定される UNIQUE 制約と同じで有る。

key 要素を使用して CustomerID 要素のキー制約を指定するスキーマの例を次に示す。

<xs:schema id="cod"

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="Customers">

<xs:complexType>

<xs:sequence>

<xs:element name="CustomerID" type="xs:string" minOccurs="0" />

<xs:element name="CompanyName" type="xs:string" minOccurs="0" />

<xs:element name="Phone" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

Page 34: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-34-

<xs:element ref="Customers" />

</xs:choice>

</xs:complexType>

<xs:key msdata:PrimaryKey="true"

msdata:ConstraintName="KeyCustID"

name="KeyConstCustomerID" >

<xs:selector xpath=".//Customers" />

<xs:field xpath="CustomerID" />

</xs:key>

</xs:element>

</xs:schema>

key 要素は、Customers 要素の CustomerID 子要素の値を一意の値にし、null 値を許可しない様に

指定する。XML スキーマ定義言語(XSD)スキーマの変換では、割り当て処理に依って次のテーブル

が作成される。

Customers(CustomerID, CompanyName, Phone)

亦、次の DataSet に示す様に、XMLスキーマの割り当てに依ってCustomerID 列の UniqueConstraint

を作成する事も出来る(わかりやすい様に、関連するプロパティ丈を示す)。

DataSetName: MyDataSet

TableName: customers

ColumnName: CustomerID

AllowDBNull: False

Unique: True

ConstraintName: KeyCustID

Table: customers

Columns: CustomerID

IsPrimaryKey: True

生成される DataSet では、スキーマの Key 要素で msdata:PrimaryKey="true" が指定される為、

UniqueConstraint の IsPrimaryKey プロパティが true に設定される。

DataSet に有る UniqueConstraint の ConstraintName プロパティの値は、スキーマの key 要素で指

定した msdata:ConstraintName 属性の値で有る。

・XML スキーマ(XSD)のキー参照制約の DataSet 制約への割り当て

keyref 要素を使用すると、ドキュメント内の要素間にリンクを確立出来る。此れは、リレーショナル

データベースの外部キーのリレーションシップと同様で有る。スキーマに keyref 要素を指定すると、

スキーマの割り当て処理時に keyref 要素が其れに対応する DataSet の列の外部キー制約に変換される。

既定では、keyref 要素に依ってリレーションも生成され、リレーションに ParentColumn、ChildTable、

ParentColumn 及び ChildColumn プロパティが指定される。

keyref 要素で指定できる msdata 属性を次の表に示す。

属性名 説明

msdata:ConstraintOnly スキーマの keyref 要素で ConstraintOnly="true" を指定した場合、制

約が作成されるが、リレーションは作成されません。此の属性を指定し

ない(又は False に設定する) 場合、制約及びリレーションが DataSet

に作成される。

Page 35: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-35-

msdata:ConstraintName ConstraintName 属性を指定した場合、其の値が制約名と仕て使用され

る。其れ以外の場合、スキーマの keyref 要素の name 属性に依って

DataSet の制約名が設定される。

msdata:UpdateRule スキーマの keyref 要素で UpdateRule 属性を指定した場合、其の値が

DataSet の UpdateRule 制約プロパティに割り当てられます。其れ以外

の場合、UpdateRule プロパティは Cascade に設定される。

msdata:DeleteRule スキーマの keyref 要素で DeleteRule 属性を指定した場合、其の値が

DataSet の DeleteRule 制約プロパティに割り当てられます。其れ以外

の場合、DeleteRule プロパティは Cascade に設定される。

msdata:AcceptRejectRule スキーマの keyref 要素で AcceptRejectRule 属性を指定した場合、其の

値が DataSet の AcceptRejectRule 制約プロパティに割り当てられま

す。其れ以外の場合、AcceptRejectRule プロパティは None に設定さ

れる。

Order 要素の OrderNumber 子要素と OrderDetail 要素の OrderNo 子要素間のリレーションシップ

を指定する key 属性と keyref 属性を含むスキーマを次の例に示す。

例では、OrderDetail 要素の OrderNumber 子要素が Order 要素の OrderNo キーの子要素を参照す

る。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="OrderDetail">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:integer" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:integer" />

<xs:element name="EmpNumber" type="xs:integer" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

<xs:key name="OrderNumberKey" >

<xs:selector xpath=".//Order" />

<xs:field xpath="OrderNumber" />

</xs:key>

Page 36: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-36-

<xs:keyref name="OrderNoRef" refer="OrderNumberKey">

<xs:selector xpath=".//OrderDetail" />

<xs:field xpath="OrderNo" />

</xs:keyref>

</xs:element>

</xs:schema>

XML スキーマ定義言語(XSD)スキーマの割り当て処理に依って、2 つのテーブルを持つ次の DataSet

が生成される。

OrderDetail(OrderNo, ItemNo) and

Order(OrderNumber, EmpNumber)

さらに、DataSet に依って次の制約が定義される。

Order テーブルの UNIQUE 制約。

Table: Order

Columns: OrderNumber

ConstraintName: OrderNumberKey

Type: UniqueConstraint

IsPrimaryKey: False

Order テーブルと OrderDetail テーブル間のリレーションシップ。スキーマの 2 つの要素が入れ子に

なって居ない為、Nested プロパティは False に設定される。

ParentTable: Order

ParentColumns: OrderNumber

ChildTable: OrderDetail

ChildColumns: OrderNo

ParentKeyConstraint: OrderNumberKey

ChildKeyConstraint: OrderNoRef

RelationName: OrderNoRef

Nested: False

OrderDetail テーブルの外部キー制約。

ConstraintName: OrderNoRef

Type: ForeignKeyConstraint

Table: OrderDetail

Columns: OrderNo

RelatedTable: Order

RelatedColumns: OrderNumber

XML スキーマ(XSD)からの DataSet リレーションの生成

DataSet では、親子のリレーションを作成する事により、2 つ以上の列間の関連付けを行う。XML ス

キーマ定義言語(XSD)スキーマ内で DataSet のリレーションを表すには、次の 3 つの方法が有る。

・入れ子になった複合型を指定する方法

・msdata:Relationship 注釈を使用する方法

・msdata:ConstraintOnly 注釈を使用せずに xs:keyref を指定する方法

Page 37: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-37-

・入れ子になった複合型

スキーマ内で複数の複合型の定義が入れ子になって居る場合は、其等の入れ子状の要素間に親子のリレ

ーションシップが有る。OrderDetail が Order 要素の子要素で有る事を示す XML スキーマのフラグ

メントを次に示す。

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderDetail" />

<xs:complexType>

</xs:complexType>

</xs:sequence>

</xs:complexType>

</xs:element>

XML スキーマの割り当て処理に依って、スキーマの入れ子になった複合型に対応する DataSet にテー

ブルが作成される。亦、生成されたテーブルの親子列と仕て使用される追加列も作成される。其の親子

列ではリレーションシップが指定されるが、主キー制約や外部キー制約の指定とは異なる為注意してく

ださい。

・msdata:Relationship 注釈

msdata:Relationship 注釈を使用すると、入れ子になって居ないスキーマの要素間の親子のリレーショ

ンシップを明示的に指定出来る。Relationship 要素の構造を示す例を次に示す。

<msdata:Relationship name="CustOrderRelationship"

msdata:parent="" msdata:child="" msdata:parentkey="" msdata:childkey="" />

msdata:Relationship 注釈の属性は、リレーションシップに必要な parentkey 要素と childkey 要素、

及び属性と同様に親子のリレーションシップに必要な要素を示す。割り当て処理では、其の情報に基づ

いて DataSet にテーブルを作成し、其等のテーブル間に主キー/外部キーのリレーションシップを作成

する。

たとえば、同じレベルで(入れ子にせずに) Order 要素と OrderDetail 要素を指定するスキーマのフラ

グメントを次に示す。スキーマに msdata:Relationship 注釈を指定すると、其の 2 つの要素間に親子

のリレーションシップが指定される。此の場合、msdata:Relationship 注釈を使用してリレーションシ

ップを明示的に指定する必要が有る。

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="OrderDetail">

<xs:complexType>

</xs:complexType>

</xs:element>

<xs:element name="Order">

<xs:complexType>

Page 38: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-38-

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

<xs:annotation>

<xs:appinfo>

<msdata:Relationship name="OrdOrdDetailRelation"

msdata:parent="Order"

msdata:child="OrderDetail"

msdata:parentkey="OrderNumber"

msdata:childkey="OrderNo"/>

</xs:appinfo>

</xs:annotation>

割り当て処理では、Relationship 要素を使用して、DataSetに有るOrder テーブルのOrderNumber 列

と OrderDetail テーブルの OrderNo 列に親子のリレーションシップが生成される。割り当て処理で指

定されるのはリレーションシップ丈で、リレーショナルデータベースにおける主キー制約や外部キー制

約の場合とは異なり、該当する列の値に対する制約が自動的に指定される事は有りません。

・入れ子になって居るスキーマ要素間の暗黙的なリレーションの割り当て

XML スキーマ言語定義 (XSD) スキーマでは、複数の複合型を入れ子にして指定出来る。此の場合、割

り当て処理には既定の割り当てが適用される。其の際、DataSet に作成される内容を次に示す。

・複合型 (親及び子) それぞれに対して 1 つのテーブル。

・親に UNIQUE 制約がなく、親テーブル名が TableName で有る場合は、TableName_Id と謂う名前

の主キー列が、テーブル定義毎に 1 つ追加される。

・親テーブルの主キー制約により、追加された列が主キーと仕て認識される(IsPrimaryKey プロパティ

を True に設定する事で)。制約には、Constraint# (# は、1、2、3 等)と謂う名前が付けられます。

たとえば、最初の制約の既定の名前は Constraint1 となります。

・子テーブルの外部キー制約により、追加された列が親テーブルの主キーを参照する外部キーと仕て認

識される。親テーブル名が ParentTable、子テーブル名が ChildTable の場合には、制約の名前は

ParentTable_ChildTable となります。

・其の結果、親テーブルと子テーブル間のデータが関連付けられます。

OrderDetail が Order 要素の子要素で有る事を示すスキーマの例を次に示す。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:string" />

<xs:element name="EmpNumber" type="xs:string" />

Page 39: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-39-

<xs:element name="OrderDetail">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:string" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

XML スキーマの割り当て処理に依って DataSet に作成される内容は、次のとおりで有る。

Order 及び OrderDetail テーブル。

Order(OrderNumber, EmpNumber, Order_Id)

OrderDetail(OrderNo, ItemNo, Order_Id)

Order テーブルの UNIQUE 制約。IsPrimaryKey プロパティは True に設定されるので注意してくだ

さい。

ConstraintName: Constraint1

Type: UniqueConstraint

Table: Order

Columns: Order_Id

IsPrimaryKey: True

OrderDetail テーブルの外部キー制約。

ConstraintName: Order_OrderDetail

Type: ForeignKeyConstraint

Table: OrderDetail

Columns: Order_Id

RelatedTable: Order

RelatedColumns: Order_Id

Order テーブルと OrderDetail テーブル間のリレーションシップ。スキーマの Order 要素と

OrderDetail 要素が入れ子になって居る為、此のリレーションシップの Nested プロパティは True に

設定される。

ParentTable: Order

ParentColumns: Order_Id

ChildTable: OrderDetail

ChildColumns: Order_Id

ParentKeyConstraint: Constraint1

ChildKeyConstraint: Order_OrderDetail

RelationName: Order_OrderDetail

Nested: True

Page 40: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-40-

・入れ子になって居る要素に指定したリレーションシップの割り当て

スキーマには、其の中の 2 つの要素間の割り当てを明示的に指定する為に、msdata:Relationship 注釈

をインクルードする事が出来る。msdata:Relationship で指定されたスキーマの 2 つの要素は、必要に

応じて、入れ子にする事が出来る。割り当て処理では、スキーマの msdata:Relationship を使用して 2

つの列間に主キー/外部キーのリレーションシップを生成する。

OrderDetail 要素が Order の子要素で有る事を示す XML スキーマの例を次に示す。

msdata:Relationship は此の親子のリレーションシップを識別し、生成された Order テーブルの

OrderNumber 列と生成された OrderDetail テーブルの OrderNo 列が関連付けられて居る事を示す。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:string" />

<xs:element name="EmpNumber" type="xs:string" />

<xs:element name="OrderDetail">

<xs:annotation>

<xs:appinfo>

<msdata:Relationship name="OrdODRelation"

msdata:parent="Order"

msdata:child="OrderDetail"

msdata:parentkey="OrderNumber"

msdata:childkey="OrderNo"/>

</xs:appinfo>

</xs:annotation>

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:string" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

</xs:schema>

XML スキーマの割り当て処理に依って DataSet に作成される内容は、次のとおりで有る。

Order 及び OrderDetail テーブル。

Page 41: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-41-

Order(OrderNumber, EmpNumber)

OrderDetail(OrderNo, ItemNo)

Order テーブルと OrderDetail テーブル間のリレーションシップ。スキーマの Order 要素と

OrderDetail 要素が入れ子になって居る為、此のリレーションシップの Nested プロパティは True に

設定される。

ParentTable: Order

ParentColumns: OrderNumber

ChildTable: OrderDetail

ChildColumns: OrderNo

RelationName: OrdODRelation

Nested: True

割り当て処理に依って制約は作成されません。

・入れ子になって居ない要素間のリレーションの指定

要素が入れ子になって居ない場合、暗黙的なリレーションは作成されません。其れに対し、

msdata:Relationship 注釈を使用すると、入れ子になって居ない要素間にリレーションを明示的に指定

出来る。

互いに入れ子になって居ないOrder 要素とOrderDetail 要素の間にmsdata:Relationship 注釈を指定

する XML スキーマの例を次に示す。msdata:Relationship 注釈は、Schema 要素の子要素と仕て指定

する。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="OrderDetail">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:string" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:string" />

<xs:element name="EmpNumber" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

</xs:element>

Page 42: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-42-

<xs:annotation>

<xs:appinfo>

<msdata:Relationship name="OrdOrderDetailRelation"

msdata:parent="Order"

msdata:child="OrderDetail"

msdata:parentkey="OrderNumber"

msdata:childkey="OrderNo"/>

</xs:appinfo>

</xs:annotation>

</xs:schema>

次に示す様に、XML スキーマ定義言語(XSD)スキーマの割り当て処理に依って、Order テーブルと

OrderDetail テーブルを含む DataSet が生成され、其等のテーブル間にリレーションシップが指定され

る。

RelationName: OrdOrderDetailRelation

ParentTable: Order

ParentColumns: OrderNumber

ChildTable: OrderDetail

ChildColumns: OrderNo

Nested: False

制約とリレーションシップ間の相互関係に付いて

XML スキーマ定義言語(XSD)スキーマでは、制約 (UNIQUE、キー、キー参照) 及びリレーション

シップ (msdata:Relationship 注釈を使用した) を指定出来る。此の資料では、XML スキーマで指定し

た制約及びリレーションシップを解釈して DataSet を生成する方法に付いて説明する。

一般的に、 XML スキーマでは DataSet にリレーションシップ丈を生成する場合に、

msdata:Relationship 注釈を指定する。詳細に付いては、「XML スキーマ(XSD)からの DataSet リ

レーションの生成」を参照され度い。DataSet に制約を生成する場合は、制約 (UNIQUE、キー、及び

キー参照) を指定する。此の資料の後に説明されて居る様に、リレーションシップを生成するにはキー

制約とキー参照制約も使用するので注意してください。

・キー制約及びキー参照制約に依るリレーションシップの生成

msdata:Relationship 注釈を指定する代わりに、XML スキーマの割り当て処理時に使用するキー制約

とキー参照制約を指定し、制約丈でなく、DataSet のリレーションシップも生成する事が出来る。但し、

keyref 要素で msdata:ConstraintOnly="true" を指定した場合、DataSet には制約丈が作成され、リ

レーションシップは生成されません。

入れ子になって居ない Order 要素と OrderDetail 要素を含む XML スキーマの例を次に示す。スキー

マでは、キー制約とキー参照制約も指定する。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="OrderDetail">

Page 43: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-43-

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:integer" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:integer" />

<xs:element name="EmpNumber" type="xs:integer" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

<xs:key name="OrderNumberKey" >

<xs:selector xpath=".//Order" />

<xs:field xpath="OrderNumber" />

</xs:key>

<xs:keyref name="OrderNoRef" refer="OrderNumberKey">

<xs:selector xpath=".//OrderDetail" />

<xs:field xpath="OrderNo" />

</xs:keyref>

</xs:element>

</xs:schema>

XML スキーマの割り当て処理時に生成される DataSet には、Order テーブルと OrderDetail テーブ

ルが含まれる。さらに、DataSet にはリレーションシップと制約も含まれる。其のリレーションシップ

と制約の例を次に示す。スキーマでは、msdata:Relationship 注釈が指定されない事に注意してくださ

い。代わりに、キー制約とキー参照制約を使用してリレーションを生成する。

....ConstraintName: OrderNumberKey

....Type: UniqueConstraint

....Table: Order

....Columns: OrderNumber

....IsPrimaryKey: False

....ConstraintName: OrderNoRef

....Type: ForeignKeyConstraint

....Table: OrderDetail

....Columns: OrderNo

....RelatedTable: Order

....RelatedColumns: OrderNumber

..RelationName: OrderNoRef

..ParentTable: Order

..ParentColumns: OrderNumber

..ChildTable: OrderDetail

Page 44: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-44-

..ChildColumns: OrderNo

..ParentKeyConstraint: OrderNumberKey

..ChildKeyConstraint: OrderNoRef

..Nested: False

上記のスキーマの例では、Order 要素と OrderDetail 要素は入れ子になって居ない。入れ子になって

居る Order 要素と OrderDetail 要素を含むスキーマの例を次に示す。但し、msdata:Relationship 注

釈が指定されて居ない為、暗黙のリレーションが適用される。詳細に付いては、「入れ子になって居る

スキーマ要素間の暗黙的なリレーションの割り当て」を参照され度い。スキーマでは、キー制約とキー

参照制約も指定する。

<xs:schema id="MyDataSet" xmlns=""

xmlns:xs="http://www.w3.org/2001/XMLSchema"

xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

<xs:element name="MyDataSet" msdata:IsDataSet="true">

<xs:complexType>

<xs:choice maxOccurs="unbounded">

<xs:element name="Order">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNumber" type="xs:integer" />

<xs:element name="EmpNumber" type="xs:integer" />

<xs:element name="OrderDetail">

<xs:complexType>

<xs:sequence>

<xs:element name="OrderNo" type="xs:integer" />

<xs:element name="ItemNo" type="xs:string" />

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:sequence>

</xs:complexType>

</xs:element>

</xs:choice>

</xs:complexType>

<xs:key name="OrderNumberKey" >

<xs:selector xpath=".//Order" />

<xs:field xpath="OrderNumber" />

</xs:key>

<xs:keyref name="OrderNoRef" refer="OrderNumberKey">

<xs:selector xpath=".//OrderDetail" />

<xs:field xpath="OrderNo" />

</xs:keyref>

</xs:element>

</xs:schema>

Page 45: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-45-

XML スキーマの割り当て処理に依って生成された DataSet には、次の 2 つのテーブルが含まれる。

Order(OrderNumber, EmpNumber, Order_Id)

OrderDetail(OrderNumber, ItemNumber, Order_Id)

さらに、DataSet には 2 つのリレーションシップ (1 つは msdata:relationship 注釈に基づいた、もう

1 つはキー制約とキー参照制約に基づいた) 及び様々な制約も含まれる。リレーション及び制約の例を

次に示す。

..RelationName: Order_OrderDetail

..ParentTable: Order

..ParentColumns: Order_Id

..ChildTable: OrderDetail

..ChildColumns: Order_Id

..ParentKeyConstraint: Constraint1

..ChildKeyConstraint: Order_OrderDetail

..Nested: True

..RelationName: OrderNoRef

..ParentTable: Order

..ParentColumns: OrderNumber

..ChildTable: OrderDetail

..ChildColumns: OrderNo

..ParentKeyConstraint: OrderNumberKey

..ChildKeyConstraint: OrderNoRef

..Nested: False

..ConstraintName: OrderNumberKey

..Type: UniqueConstraint

..Table: Order

..Columns: OrderNumber

..IsPrimaryKey: False

..ConstraintName: Constraint1

..Type: UniqueConstraint

..Table: Order

..Columns: Order_Id

..IsPrimaryKey: True

..ConstraintName: Order_OrderDetail

..Type: ForeignKeyConstraint

..Table: OrderDetail

..Columns: Order_Id

..RelatedTable: Order

..RelatedColumns: Order_Id

..ConstraintName: OrderNoRef

..Type: ForeignKeyConstraint

..Table: OrderDetail

..Columns: OrderNo

..RelatedTable: Order

..RelatedColumns: OrderNumber

入れ子になって居るテーブルを参照するキー参照制約に msdata:IsNested="true" 注釈が含まれて居る

Page 46: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-46-

場合は、其のキー参照制約と関連する UNIQUE/ キー制約に基づいて、1 つの入れ子になったリレーシ

ョンシップが作成される。

■ XML からの DataSet リレーショナル構造の推論

DataSet のリレーショナル構造 (スキーマ) は、テーブル、列、制約、及びリレーションで構成される。

XML から DataSet を読み込む時には、事前定義されたスキーマを使用するか、又は読み込む対象の

XML から明示的に又は推論に依ってスキーマを作成出来る。XML から DataSet のスキーマ及び内容

を読み込む方法の詳細に付いては、「XML からの DataSet の読み込み」及び「XML の DataSet スキー

マ情報の読み込み」を参照され度い。

DataSet のスキーマを XML から作成する場合は、XML スキーマ定義言語 (「XML スキーマ(XSD)

からの DataSet リレーショナル構造の生成」を参照) 又は XDR (XML-Data Reduced) を使用してスキ

ーマを明示的に指定する事を推奨する。XML で利用できる XML スキーマ又は XDR スキーマが無い場

合は、XML の要素及び属性の構造から DataSet のスキーマを推論出来る。

ここでは、XML の要素と属性及び其の構造を示し、DataSet スキーマの推論に関する規則に付いて説

明する。亦、其の規則に基づいて推論した DataSet スキーマも示す。

XML ドキュメント内の総ての属性を推論プロセスの対象には含めないでください。名前空間で修飾さ

れた属性には、XML ドキュメントにとっては重要ですが、DataSet スキーマにとっては不要なメタデ

ータが含まれて居る事が有る。InferXmlSchema を使用して、推論プロセスの間に無視する特定の名前

空間を指定出来る。詳細に付いては、「XML の DataSet スキーマ情報の読み込み」を参照され度い。

DataSet スキーマの推論プロセスの概要

推論プロセスでは、まず、テーブルと仕て推論する XML ドキュメントの要素を決定する。XML ドキュ

メントの残りの要素から、其等のテーブルの列が推論に依って決定される。入れ子状のテーブルの場合

は、入れ子になった DataRelation オブジェクトと ForeignKeyConstraint オブジェクトが生成される。

推論規則に付いて、次に簡単に説明する。

・属性を持つ要素は、テーブルと仕て推論される。

・子要素を持つ要素は、テーブルと仕て推論される。

・繰り返し出現する要素は、単一のテーブルと仕て推論される。

・ドキュメント (ルート) 要素に属性がなく、列と仕て推論される子要素もない場合、其の要素は

DataSet と仕て推論される。其れ以外の場合は、ドキュメント要素はテーブルと仕て推論される。

・属性は、列と仕て推論される。

・属性又は子要素を持たず、繰り返し出現する事もない要素は、列と仕て推論される。

・テーブルと仕て推論される要素が、同じくテーブルと仕て推論される他の要素の内部に入れ子になっ

て居る場合は、其の 2 つのテーブル間に入れ子になった DataRelation が作成される。其の場合、

TableName_Id と謂う名前の新しい主キー列が其の両方のテーブルに追加され、DataRelation に依

っ て使用さ れる。此の TableName_Id 列 を使用し て、此の 2 つ のテー ブル間 に

ForeignKeyConstraint が作成される。

・テーブルと仕て推論される要素に、テキストは含まれて居るが子要素は含まれて居ない場合は、

Page 47: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-47-

TableName_Text と謂う名前の新しい列が各要素のテキストに作成される。テーブルと仕て推論され

る要素にテキスト丈でなく、子要素も有る場合、テキストは無視される。

テーブルの推論

XML ドキュメントから DataSet のスキーマを推論する時には、ADO.NET では、テーブルを表す XML

要素を最初に決定する。次に示す幾つかの XML 構造は、DataSet スキーマのテーブルと仕て推論され

る。

・属性を持つ要素

・子要素を持つ要素

・繰り返し出現する要素

・属性を持つ要素

要素に属性が指定されて居る場合は、其等の要素はテーブルと仕て推論される。たとえば、次の様な

XML が有るとする。

<DocumentElement>

<Element1 attr1="value1"/>

<Element1 attr1="value2">Text1</Element1>

</DocumentElement>

推論プロセスにより、"Element1"と謂う名前のテーブルが生成される。

DataSet : DocumentElement

Table: Element1

attr1 Element1_Text

value1

value2 Text1

・子要素を持つ要素

子要素を持つ要素は、テーブルと仕て推論される。たとえば、次の様な XML が有るとする。

<DocumentElement>

<Element1>

<ChildElement1>Text1</ChildElement1>

</Element1>

</DocumentElement>

推論プロセスにより、"Element1"と謂う名前のテーブルが生成される。

DataSet : DocumentElement

Table: Element1

ChildElement1

Text1

ドキュメント (ルート) 要素に属性又は子要素が有り、其等が列と仕て推論される場合には、其のドキ

ュメント要素はテーブルと仕て推論される。ドキュメント要素の属性や子要素が列と仕て推論されない

Page 48: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-48-

場合には、其のドキュメント要素は DataSet と仕て推論される。たとえば、次の様な XML が有るとす

る。

<DocumentElement>

<Element1>Text1</Element1>

<Element2>Text2</Element2>

</DocumentElement>

推論プロセスにより、"DocumentElement"と謂う名前のテーブルが生成される。

DataSet: NewDataSet

Table: DocumentElement

Element1 Element2

Text1 Text2

又は、次の様な XML が有るとする。

<DocumentElement>

<Element1 attr1="value1" attr2="value2"/>

</DocumentElement>

推論プロセスにより、"Element1"と謂う名前のテーブルを含む"DocumentElement"と謂う名前の

DataSet が生成される。

DataSet : DocumentElement

Table: Element1

attr1 attr2

value1 value2

・繰り返し出現する要素

繰り返し出現する要素は、単一のテーブルと仕て推論される。たとえば、次の様な XML が有るとする。

<DocumentElement>

<Element1>Text1</Element1>

<Element1>Text2</Element1>

</DocumentElement>

推論プロセスにより、"Element1"と謂う名前のテーブルが生成される。

DataSet : DocumentElement

Table: Element1

Element1_Text

Text1

Text2

列の推論

ADO.NET は、DataSet のテーブルと仕て推論する要素を、XML ドキュメントから決定した後、其等

のテーブルの列を推論する。ADO.NET 2.0 には、各 simpleType 要素の厳密に型指定されたデータ型

Page 49: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-49-

を推論する新しいスキーマ推論エンジンが採用される。以前のバージョンでは、推論される simpleType

要素のデータ型は、常に xsd:string でした。

・移行及び下位互換性

ReadXml メソッドは、InferSchema 型の引数を取る。此の引数を使用する事により、以前のバージョ

ンと互換性の有る推論方法を指定する事が出来る。InferSchema 列挙体で使用できる値を、次の表に

示す。

InferSchema:単純型を String と仕て常に推論する事で下位互換性を提供する。

InferTypedSchema:厳密に型指定されたデータ型を推論する。DataTable で使用した場合、例外をス

ローする。

IgnoreSchema:インラインスキーマを無視し、データを既存の DataSet スキーマに読み取る。

・属性

「テーブルの推論」で説明したとおり、属性を持つ要素は、テーブルと仕て推論される。其の要素の属

性は、其のテーブルの列と仕て推論される。スキーマが XML に書き戻される場合に、列の名前が確実

に 属 性 と 仕 て 書 き 込 ま れ る 様 に 、 推 論 さ れ た 列 の ColumnMapping プ ロ パ テ ィ は

MappingType.Attribute に設定される。属性の値は、テーブルの行に格納される。たとえば、次の様

な XML が有るとする。

<DocumentElement>

<Element1 attr1="value1" attr2="value2"/>

</DocumentElement>

推論プロセスにより、attr1 及び attr2 と謂う 2 つの列を持つ Element1 と謂う名前のテーブルが生

成される。2 つの列の ColumnMapping プロパティは、MappingType.Attribute に設定される。

DataSet : DocumentElement

Table: Element1

attr1 attr2

value1 value2

・属性又は子の要素を持たない要素

要素に子の要素又は属性が無い場合、其の要素は列と仕て推論される。列の ColumnMapping プロパテ

ィは、MappingType.Element に設定される。子の要素のテキストは、テーブルの行に格納される。た

とえば、次の様な XML が有るとする。

<DocumentElement>

<Element1>

<ChildElement1>Text1</ChildElement1>

<ChildElement2>Text2</ChildElement2>

</Element1>

</DocumentElement>

推論プロセスにより、ChildElement1 及び ChildElement2 と謂う 2 つの列を持つ Element1 と謂う

名前のテーブルが生成される。2 つの列の ColumnMapping プロパティは、MappingType.Element に

Page 50: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-50-

設定される。

DataSet : DocumentElement

Table: Element1

ChildElement1 ChildElement2

Text1 Text2

リレーションシップの推論

テーブルと仕て推論される要素に、同じくテーブルと仕て推論される子の要素が含まれて居る場合には、

2 つのテーブル間に DataRelation が作成される。此の場合、ParentTableName_Id と謂う名前の新し

い列が、親の要素に対して作成されたテーブルと、子の要素に対して作成されたテーブルの両方に追加

される。此の ID 列の ColumnMapping プロパティは、MappingType.Hidden に設定される。此の列

が、親テーブルの自動的にインクリメントされる主キーとなり、2 つのテーブル間の DataRelation で

使用される。推論される他の総ての列のデータ型は System.String になりますが、追加される ID 列の

データ型は System.Int32 になります。親テーブル及び子テーブルの両方に追加された此の新しい列を

使用して、DeleteRule = Cascade で有る ForeignKeyConstraint も作成される。

たとえば、次の様な XML が有るとする。

<DocumentElement>

<Element1>

<ChildElement1 attr1="value1" attr2="value2"/>

<ChildElement2>Text2</ChildElement2>

</Element1>

</DocumentElement>

推論プロセスにより、Element1 及び ChildElement1 と謂う名前の 2 つのテーブルが生成される。

Element1 テーブルには、Element1_Id 及び ChildElement2 と謂う名前の 2 つの列が有る。

Element1_Id 列の ColumnMapping プロパティは、 MappingType.Hidden に設定される。

ChildElement2 列の ColumnMapping プロパティは、MappingType.Element に設定される。

Element1_Id 列は、Element1 テーブルの主キーと仕て設定される。

ChildElement1 テーブルには、attr1、attr2、及び Element1_Id と謂う名前の 3 つの列が有る。attr1

列及び attr2 列の ColumnMapping プロパティは、MappingType.Attribute に設定される。

Element1_Id 列の ColumnMapping プロパティは、MappingType.Hidden に設定される。

2 つのテーブルの Element1_Id 列を使用して、DataRelation 及び ForeignKeyConstraint が作成され

る。

DataSet: DocumentElement

Table: Element1

Element1_Id ChildElement2

0 Text2

Table: ChildElement1

attr1 attr2 Element1_Id

value1 value2 0

Page 51: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-51-

DataRelation: Element1_ChildElement1

ParentTable: Element1

ParentColumn: Element1_Id

ChildTable: ChildElement1

ChildColumn: Element1_Id

Nested: True

ForeignKeyConstraint: Element1_ChildElement1

Column: Element1_Id

ParentTable: Element1

ChildTable: ChildElement1

DeleteRule: Cascade

AcceptRejectRule: None

要素のテキストの推論

要素にテキストは含まれて居るが、テーブルと仕て推論される(属性を持つ要素又は繰り返し出現する要

素等の) 子の要素が無い場合は、TableName_Text と謂う名前の新しい列が、要素に対して推論される

テーブルに追加される。要素に含まれて居るテキストはテーブルの行に追加され、新しい列に格納され

る。新しい列の ColumnMapping プロパティは、MappingType.SimpleContent に設定される。

たとえば、次の様な XML が有るとする。

<DocumentElement>

<Element1 attr1="value1">Text1</Element1>

</DocumentElement>

推論プロセスにより、attr1 及び Element1_Text と謂う 2 つの列を持つ Element1 と謂う名前のテー

ブルが生成される。attr1 列の ColumnMapping プロパティは、MappingType.Attribute に設定され

る。Element1_Text 列の ColumnMapping プロパティは、MappingType.SimpleContent に設定され

る。

DataSet: DocumentElement

Table: Element1

attr1 Element1_Text

value1 Text1

要素にテキスト丈でなく、テキストを含む子の要素も含まれて居る場合は、其の要素に含まれて居るテ

キストを格納する為の列はテーブルに追加されません。要素に含まれるテキストは無視されるが、子の

要素のテキストはテーブルの行に追加される。たとえば、次の様な XML が有るとする。

<Element1>

Text1

<ChildElement1>Text2</ChildElement1>

Text3

</Element1>

推論プロセスにより、ChildElement1 と謂う 1 つの列を持つ Element1 と謂う名前のテーブルが生成

される。ChildElement1 要素のテキストは、テーブルの行に追加される。其の他のテキストは無視さ

れる。ChildElement1 列の ColumnMapping プロパティは、MappingType.Element に設定される。

DataSet: DocumentElement

Page 52: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-52-

Table: Element1

ChildElement1

Text2

推論の制限事項

各ドキュメントに含まれて居る XML 要素に依っては、XML から DataSet のスキーマを推論するプロ

セスにより、異なるスキーマが生成される可能性が有る。たとえば、次の様な XML ドキュメントが有

るとする。

Document1:

<DocumentElement>

<Element1>Text1</Element1>

<Element1>Text2</Element1>

</DocumentElement>

Document2:

<DocumentElement>

<Element1>Text1</Element1>

</DocumentElement>

推論プロセスでは、 "Document1" に付いては、 "DocumentElement"と謂う名前の DataSet と

"Element1"と謂う名前のテーブルが作成される。此れは、"Element1" が繰り返し出現する要素で有る

為で有る。

DataSet: DocumentElement

Table: Element1

Element1_Text

Text1

Text2

此 れ に 対 し て 、 "Document2" に 付 い て は 、 "NewDataSet" と 謂 う 名 前 の DataSet と

"DocumentElement"と謂う名前のテーブルが生成される。此の場合、属性も子要素も持たない

"Element1" は列と仕て推論される。

DataSet: NewDataSet

Table: DocumentElement

Element1

Text1

此れらの 2 つの XML ドキュメントは、同じスキーマを生成する事を意図して記述されて居るが、推論

プロセスでは、各ドキュメントに含まれる要素を基にまったく異なるスキーマが生成されてしまいます。

XML ドキュメントからスキーマを生成する時に生じる可能性の有る此の様な矛盾を避ける為、XML か

ら DataSet を読み込む時は、XSD (XML スキーマ定義言語) 又は XDR (XML-Data Reduced) を使用

して、スキーマを明示的に指定する事を推奨する。XML スキーマを使用して DataSet スキーマを明示

的に指定する方法に付いては、「XML スキーマ(XSD)からの DataSet リレーショナル構造の生成」

を参照され度い。

Page 53: DataSet - XMLjunko036.html.xdomain.jp/pdf/database/DataSet_XML.pdfADO.NET では、他のアプリケーションやXML対応プラットフォームでDataSetが使用される場合に、

VS 2005 資料 【電脳梁山泊 烏賊塾】

-53-