DataSet に対する XPath クエリの実行
同期された DataSet と XmlDataDocument との間の関係によって、XML Path Language (XPath) クエリなどの 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 の製品を注文した顧客を確認します。
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Xml
Public Class Sample
Public Shared Sub Main()
Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Initial Catalog=northwind;Integrated Security=SSPI")
nwindConn.Open()
Dim myDataSet As DataSet = New DataSet("CustomerOrders")
Dim custDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Customers", nwindConn)
custDA.Fill(myDataSet, "Customers")
Dim ordersDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM Orders", nwindConn)
ordersDA.Fill(myDataSet, "Orders")
Dim detailsDA As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM [Order Details]", nwindConn)
detailsDA.Fill(myDataSet, "OrderDetails")
nwindConn.Close()
myDataSet.Relations.Add("CustOrders", _
myDataSet.Tables("Customers").Columns("CustomerID"), _
myDataSet.Tables("Orders").Columns("CustomerID")).Nested = true
myDataSet.Relations.Add("OrderDetail", _
myDataSet.Tables("Orders").Columns("OrderID"), _
myDataSet.Tables("OrderDetails").Columns("OrderID"), false).Nested = true
Dim xmlDoc As XmlDataDocument = New XmlDataDocument(myDataSet)
Dim nodeList As XmlNodeList = xmlDoc.DocumentElement.SelectNodes("descendant::Customers[*/OrderDetails/ProductID=43]")
Dim myRow As DataRow
Dim myNode As XmlNode
For Each myNode In nodeList
myRow = xmlDoc.GetRowFromElement(CType(myNode, XmlElement))
If Not myRow Is Nothing then Console.WriteLine(myRow(0).ToString())
Next
End Sub
End Class
[C#]
using System;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
public class Sample
{
public static void Main()
{
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Initial Catalog=northwind;Integrated Security=SSPI;");
nwindConn.Open();
DataSet myDataSet = new DataSet("CustomerOrders");
SqlDataAdapter custDA = new SqlDataAdapter("SELECT * FROM Customers", nwindConn);
custDA.Fill(myDataSet, "Customers");
SqlDataAdapter ordersDA = new SqlDataAdapter("SELECT * FROM Orders", nwindConn);
ordersDA.Fill(myDataSet, "Orders");
SqlDataAdapter detailsDA = new SqlDataAdapter("SELECT * FROM [Order Details]", nwindConn);
detailsDA.Fill(myDataSet, "OrderDetails");
nwindConn.Close();
myDataSet.Relations.Add("CustOrders",
myDataSet.Tables["Customers"].Columns["CustomerID"],
myDataSet.Tables["Orders"].Columns["CustomerID"]).Nested = true;
myDataSet.Relations.Add("OrderDetail",
myDataSet.Tables["Orders"].Columns["OrderID"],
myDataSet.Tables["OrderDetails"].Columns["OrderID"], false).Nested = true;
XmlDataDocument xmlDoc = new XmlDataDocument(myDataSet);
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("descendant::Customers[*/OrderDetails/ProductID=43]");
DataRow myRow;
foreach (XmlNode myNode in nodeList)
{
myRow = xmlDoc.GetRowFromElement((XmlElement)myNode);
if (myRow != null)
Console.WriteLine(myRow[0]);
}
}
}