Realizar una consulta de XPath en DataSet (ADO.NET)
Actualización: November 2007
La relación entre un DataSet y un XmlDataDocument sincronizados le permite utilizar servicios XML, como la consulta XPath (XML Path Language), que tiene acceso al XmlDataDocument y puede realizar ciertas funciones más cómodamente que si tuviera acceso directamente al DataSet. Por ejemplo, en lugar de utilizar el método Select de una DataTable para navegar por relaciones con otras tablas de un DataSet, puede realizar una consulta de XPath en un XmlDataDocument sincronizado con el DataSet para obtener una lista de elementos XML en forma de una XmlNodeList. Los nodos de la XmlNodeList, convertidos en nodos XmlElement, se pueden pasar entonces al método GetRowFromElement del XmlDataDocument para devolver referencias de DataRow coincidentes con las filas de la tabla del DataSet sincronizado.
Por ejemplo, en el siguiente ejemplo de código se realiza una consulta "secundaria" de XPath. El DataSet se rellena con tres tablas: Customers, Orders y OrderDetails. En el ejemplo se crea primero una relación primaria-secundaria entre las tablas Customers y Orders, y entre las tablas Orders y OrderDetails. Después se realiza una consulta XPath para devolver una XmlNodeList de nodos de Customers, donde un nodo secundario de OrderDetails tiene un nodo ProductID con el valor 43. El ejemplo utiliza la consulta XPath para determinar qué clientes han pedido el producto cuyo ProductID es 43.
' 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
For Each xmlNode In nodeList
dataRow = xmlDoc.GetRowFromElement(CType(xmlNode, XmlElement))
If Not dataRow Is Nothing then Console.WriteLine(xmlRow(0).ToString())
Next
// 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]);
}