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>
<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-9831</Phone>
</Shippers>
<Shippers>
<ShipperID>2</ShipperID>
<CompanyName>United Package</CompanyName>
<Phone>(503) 555-3199</Phone>
</Shippers>
<Shippers>
<ShipperID>3</ShipperID>
<CompanyName>Federal Shipping</CompanyName>
<Phone>(503) 555-9931</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>
<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: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>
<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 ドキュメントが注文処理の次のステップ (社内の出荷部門) に渡されます。
Imports System
Imports System.Data
Imports System.Xml
Imports Northwind.FillOrder
Public class Sample
Public Shared Sub Main()
Dim orderDS As OrderDetail = New OrderDetail
Dim xmlDoc As XmlDataDocument = New XmlDataDocument(orderDS)
xmlDoc.Load("Order.xml")
Dim myItem As OrderDetail.LineItem
Dim myProd As OrderDetail.Product
For Each myItem In orderDS.LineItems
myProd = myItem.Product
' Remove quantity from the current stock.
myProd.UnitsInStock = CType(myProd.UnitsInStock - myItem.Quantity, Short)
' If the remaining stock is less than the reorder level, order more.
If ((myProd.UnitsInStock + myProd.UnitsOnOrder) < myProd.ReorderLevel) Then
myProd.UnitsOnOrder = CType(myProd.UnitsOnOrder + myProd.ReorderLevel, Short)
End If
Next
xmlDoc.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 xmlDoc = new XmlDataDocument(orderDS);
xmlDoc.Load("Order.xml");
foreach (OrderDetail.LineItem myItem in orderDS.LineItems)
{
OrderDetail.Product myProd = myItem.Product;
// Remove quantity from the current stock.
myProd.UnitsInStock = (short)(myProd.UnitsInStock - myItem.Quantity);
// If the remaining stock is less than the reorder level, order more.
if ((myProd.UnitsInStock + myProd.UnitsOnOrder) < myProd.ReorderLevel)
myProd.UnitsOnOrder = (short)(myProd.UnitsOnOrder + myProd.ReorderLevel);
}
xmlDoc.Save("Order_out.xml");
}
}