Colaboraciones en el Guille

Uso de XMLDataDocument en aplicaciones Web ASP .Net

Un ejemplo sencillo y práctico 

Fecha: 12/Ene/2006 (12 de Enero de 2006)
Autor: Ing. Fernando Luque Sánchez

fls2307@hotmail.com



Sres. Desarrolladores, nuevamente para compartir con ustedes sobre el apasionante tema del desarrollo y la programación de aplicaciones Web ASP .Net utilizando Visual Basic .Net

El artículo anterior tiene una explicación mas amplia (parte teórica siempre necesaria)
http://www.elguille.info/colabora/NET2006/FernandoLuque_ASPyXML.htm

Artículos relacionados:

Controles de lista enlazados a base de datos
http://www.elguille.info/colabora/NET2005/FernandoLuque_ControlesListaBD.htm

DataSets tipificados y no Tipificados
http://www.elguille.info/colabora/NET2005/FernandoLuque_DataSetsI.htm
http://www.elguille.info/colabora/NET2005/FernandoLuque_DataSetsII.htm
http://www.elguille.info/colabora/NET2005/FernandoLuque_TypedDataSetI.htm

Typed DataSet: Ejercicio
http://www.elguille.info/colabora/NET2005/FernandoLuque_TypedDataSetII.htm
http://www.elguille.info/colabora/NET2005/FernandoLuque_TypedDataSet03.htm

Algo de controles básico
http://www.elguille.info/colabora/NET2005/FernandoLuque_ControlesBasicos.htm

Para el manejo de Vistas
http://www.elguille.info/colabora/NET2005/FernandoLuque_FiltrosOrdenamientos.htm

Como ven... casi todo para que dominen este apasionante mundo del desarrollo.

XMLDataDocument

Esta clase extiende XMLDocument. Permite cargar datos relacionales o datos XML y manipularlos utilizando Document Object Model (DOM) del Consorcio W3C. DOM presenta los datos como una jerarquía de objetos de nodo. Dado que XmlDataDocument implementa la interfaz IXPathNavigable, también se puede utilizar como documento de origen de la clase XslTransform.

XmlDataDocument tiene una relación estrecha con la clase DataSet que proporciona una vista relacional de los datos XML cargados. Los cambios efectuados en XmlDataDocument se reflejan en DataSet y viceversa.

Para cargar DataSet con datos XML, utilice ReadXmlSchema para generar una asignación relacional. A continuación, los datos XML se pueden cargar mediante Load o LoadXML

Para cargar datos relacionales, especifique el DataSet que contenga los datos relacionales como parámetro del constructor XmlDocument.
Fuente: Ayuda de Visual Studio 2003

El ejemplo

Quiero compartir con ustedes este tema muy interesante, la comunicación a través de diferentes sistemas heterogeneos se da conversando el mismo idioma: XML.

En esta ocasión quiero resaltar la forma de como se forma un archivo Nested XML, este se forma activando la propiedad Nested del objeto DataRelation utilizado al escribir el archivo XML. Nuestro ejemplo en est ocasión simplemente lee el archivo, este se muestra mas o menos así...


 <?
xml version="1.0" standalone="yes" ?>  
< NewDataSet
>
- <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
-< xs:element name =" NewDataSet" msdata:IsDataSet =" true" msdata:Locale =" es-PE">
-< xs:complexType
>
-< xs:choice maxOccurs =" unbounded
">
-< xs:element name =" Categorias
">
-< xs:complexType
>
-< xs:sequence
>
 
<xs:element name=" categoryId" type=" xs:int" minOccurs="0" /> 
 
<xs:element name=" CategoryName" type=" xs:string" minOccurs="0" /> 
 
< xs:element name =" Description" type =" xs:string" minOccurs =" 0" />
-< xs:element name =" Productos" minOccurs =" 0" maxOccurs =" unbounded
">
-< xs:complexType
>
-< xs:sequence
>
 
<xs:element name=" ProductID" type=" xs:int" minOccurs="0" /> 
 
<xs:element name=" ProductName" type=" xs:string" minOccurs="0" /> 
 
<xs:element name=" SupplierID" type=" xs:int" minOccurs="0" /> 
 
<xs:element name=" CategoryID" type=" xs:int" minOccurs="0" /> 
 
<xs:element name=" QuantityPerUnit" type=" xs:string" minOccurs="0" /> 
 
<xs:element name=" UnitPrice" type=" xs:decimal" minOccurs="0" /> 
 
<xs:element name=" UnitsInStock" type=" xs:short" minOccurs="0" /> 
 
<xs:element name=" UnitsOnOrder" type=" xs:short" minOccurs="0" /> 
 
<xs:element name=" ReorderLevel" type=" xs:short" minOccurs="0" /> 
 
<xs:element name=" Discontinued" type=" xs:boolean" minOccurs="0" /> 
 
</xs:sequence>
  </xs:complexType>
  </xs:element>
  </xs:sequence>
  </xs:complexType>
  </xs:element>
  </ xs:choice >
 
</xs:complexType>
-< xs:unique name =" Constraint1">
 
<xs:selector xpath=" .//Categorias" /> 
 
<xs:field xpath=" categoryId" /> 
 
</xs:unique>
-< xs:keyref name =" CatProd" refer =" Constraint1" msdata:IsNested =" true">
 
<xs:selector xpath=" .//Productos" /> 
 
<xs:field xpath=" CategoryID" /> 
 
</xs:keyref>
  </xs:element>
</ xs:schema >
-
< Categorias >
 
< categoryId>1</categoryId> 
 
< CategoryName>Beverages</CategoryName> 
 
<Description>Soft drinks, coffees, teas, beers, and ales</Description>
-< Productos >
 
<ProductID>1</ProductID> 
 
<ProductName>Chai</ProductName> 
 
<SupplierID>1</SupplierID> 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit> 10 boxes x 20 bags</QuantityPerUnit> 
 
<UnitPrice>18.0000</UnitPrice> 
 
<UnitsInStock>39</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>10</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
 
</Productos>
-< Productos >
 
<ProductID>2</ProductID> 
 
<ProductName>Chang</ProductName> 
 
<SupplierID>1</SupplierID> 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit>24 - 12 oz bottles</QuantityPerUnit> 
 
<UnitPrice>19.0000</UnitPrice> 
 
<UnitsInStock>17</UnitsInStock> 
 
<UnitsOnOrder>40</UnitsOnOrder> 
 
<ReorderLevel>25</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
  </ Productos
>
- <Productos>
  <ProductID>24</ProductID> 
 
<ProductName>Guaraná Fantástica</ProductName> 
  < SupplierID > 10 </ SupplierID >
 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit>12 - 355 ml cans</QuantityPerUnit> 
 
<UnitPrice>4.5000</UnitPrice> 
 
<UnitsInStock>20</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>0</ReorderLevel> 
 
<Discontinued>true</Discontinued> 
 
</Productos>
-< Productos >
 
<ProductID>34</ProductID> 
 
<ProductName>Sasquatch Ale</ProductName> 
 
<SupplierID>16</SupplierID> 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit>24 - 12 oz bottles</QuantityPerUnit> 
 
<UnitPrice>14.0000</UnitPrice> 
 
<UnitsInStock>111</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>15</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
 
</Productos>
-< Productos >
 
<ProductID>35</ProductID> 
 
<ProductName>Steeleye Stout</ProductName> 
 
<SupplierID>16</SupplierID> 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit>24 - 12 oz bottles</QuantityPerUnit> 
 
<UnitPrice>18.0000</UnitPrice> 
 
<UnitsInStock>20</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>15</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
  </ Productos
>
- <Productos>
  <ProductID>38</ProductID> 
 
<ProductName>Côte de Blaye</ProductName> 
  < SupplierID > 18 </ SupplierID >
 
 
<CategoryID>1</CategoryID> 
 
<QuantityPerUnit>12 - 75 cl bottles</QuantityPerUnit> 
 
<UnitPrice>263.5000</UnitPrice> 
 
<UnitsInStock>17</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>15</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
 
</Productos>
-< Productos >
 
<ProductID>39</ProductID> 
 
<ProductName>Chartreuse verte</ProductName> 
 
<SupplierID>18</SupplierID> 
 
<CategoryID>1</CategoryID> 
<QuantityPerUnit>750 cc per bottle</QuantityPerUnit> 
 
<UnitPrice>18.0000</UnitPrice> 
 
<UnitsInStock>69</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>5</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
 
</Productos>
.
.
.

  </Categorias>
- <Categorias>
  <categoryId>2</categoryId> 
  < CategoryName > Condiments </ CategoryName >
 
 
< Description > Sweet and savory sauces, relishes, spreads, and seasonings </ Description >
-< Productos
>
 
<ProductID>3</ProductID> 
 
<ProductName>Aniseed Syrup</ProductName> 
 
<SupplierID>1</SupplierID> 
 
<CategoryID>2</CategoryID> 
 
<QuantityPerUnit>12 - 550 ml bottles</QuantityPerUnit> 
 
<UnitPrice>10.0000</UnitPrice> 
 
<UnitsInStock>13</UnitsInStock> 
 
<UnitsOnOrder>70</UnitsOnOrder> 
 
<ReorderLevel>25</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
 
</Productos>
-< Productos >
 
<ProductID>4</ProductID> 
 
<ProductName>Chef Anton's Cajun Seasoning</ProductName> 
 
<SupplierID>2</SupplierID> 
 
<CategoryID>2</CategoryID> 
 
<QuantityPerUnit>48 - 6 oz jars</QuantityPerUnit> 
 
<UnitPrice>22.0000</UnitPrice> 
 
<UnitsInStock>53</UnitsInStock> 
 
<UnitsOnOrder>0</UnitsOnOrder> 
 
<ReorderLevel>0</ReorderLevel> 
 
<Discontinued>false</Discontinued> 
</Productos>
.
.
.


En el contenido del archivo anterior llamado CatProdConEsquemaNested.XML. se pueden ver claramente las siguientes partes:

1. La definición del Esquema donde se puede notar la estructura de los elementos y los constraints o restricciones

Elemento Categorias
< xs:element name =" Categorias">

Constraint de Categorias y su nodo o Xpath respectivo
-< xs:unique name =" Constraint1
">
<xs:selector xpath=" .//Categorias" /> 

Definición de la Clave foránea de Categorías y Productos
-
< xs:keyref name =" CatProd" refer =" Constraint1" msdata:IsNested =" true">
 
<xs:selector xpath=" .//Productos" /> 
 
<xs:field xpath="CategoryID" /> 

La porción es la siguiente


 -< NewDataSet >
- < xs:schema id =" NewDataSet" xmlns ="" xmlns:xs =" http://www.w3.org/2001/XMLSchema" xmlns:msdata =" urn:schemas-microsoft-com:xml-msdata">
-< xs:element name =" NewDataSet" msdata:IsDataSet =" true" msdata:Locale =" es-PE">
-< xs:complexType >
-< xs:choice maxOccurs =" unbounded">
-< xs:element name =" Categorias">
-< xs:complexType >
-< xs:sequence >
  <xs:element name=" categoryId" type=" xs:int" minOccurs="0" /> 
  <xs:element name=" CategoryName" type=" xs:string" minOccurs="0" /> 
  < xs:element name =" Description" type =" xs:string" minOccurs =" 0" />
-< xs:element name =" Productos" minOccurs =" 0" maxOccurs =" unbounded">
-< xs:complexType >
-< xs:sequence >
  <xs:element name=" ProductID" type=" xs:int" minOccurs="0" /> 
  <xs:element name=" ProductName" type=" xs:string" minOccurs="0" /> 
  <xs:element name=" SupplierID" type=" xs:int" minOccurs="0" /> 
  <xs:element name=" CategoryID" type=" xs:int" minOccurs="0" /> 
  <xs:element name=" QuantityPerUnit" type=" xs:string" minOccurs="0" /> 
  <xs:element name=" UnitPrice" type=" xs:decimal" minOccurs="0" /> 
  <xs:element name=" UnitsInStock" type=" xs:short" minOccurs="0" /> 
  <xs:element name=" UnitsOnOrder" type=" xs:short" minOccurs="0" /> 
  <xs:element name=" ReorderLevel" type=" xs:short" minOccurs="0" /> 
  <xs:element name=" Discontinued" type=" xs:boolean" minOccurs="0" /> 
  </ xs:sequence >
  </ xs:complexType >
  </ xs:element >
  </ xs:sequence >
  </ xs:complexType >
  </ xs:element >
  </ xs:choice >
  </ xs:complexType >
-< xs:unique name =" Constraint1">
  <xs:selector xpath=" .//Categorias" /> 
  <xs:field xpath=" categoryId" /> 
  </ xs:unique >
-< xs:keyref name =" CatProd" refer =" Constraint1" msdata:IsNested =" true">
  <xs:selector xpath=" .//Productos" /> 
  <xs:field xpath=" CategoryID" /> 
  </ xs:keyref >
  </ xs:element >
</ xs:schema >


Los datos se presentan de manera jerárquica, note las lineas cambiadas a color azul donde se presenta la categoria 1 y luego los productos de esa categoria mostrados en color marrón.

El formulario se muestra asi:

Archivos XML


El código implementado para leer el archivo es:

    Private Sub cmdLeerDatos_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles cmdLeerDatos.Click

        'Leer los datos desde la carpeta personal
        'LEER EL ESQUEMA

        dsdatos.ReadXmlSchema(GetFolderPath(SpecialFolder.Personal) _
            & "\CatProdConEsquemaNested.XML")

        'LEER LOS DATOS
        dsdatos.ReadXml(GetFolderPath(SpecialFolder.Personal) _
            & "\CatProdConEsquemaNested.XML")

         'Crear el XMLDataDocument
        Dim xmlData As New XmlDataDocument(dsdatos)

        'Origen del Grid Categorias
        dgDatos.DataSource = xmlData.DataSet.Tables(0)
        dgDatos.DataBind()

        'Productos
        Dim vRel As String = dsdatos.Relations(0).RelationName
        Dim vPrimero As String = dgDatos.Items.Item(0).Cells(0).Text
        Dim mitabla As DataTable = dsdatos.Tables(1)
        Dim mifiltro As String = "Categoryid = '" & vPrimero & "'"
        Dim miorden As String = "ProductId ASC"

        'Crear la Vista
        Dim dvVista As New DataView(mitabla, mifiltro, miorden, _
            DataViewRowState.CurrentRows)

        'Origen del Grid de Productos
        dgProductos.DataSource = dvVista
        dgProductos.DataBind()

    End Sub

El código completo ya sabes que se encuentra al final del artículo, vota previamente en PanoramaBox, eso me alienta a seguir publicando.

Muy importante: En  el empaquetado incluyo el archivo XML, la carpeta de donde lo lee es  Mis documentos del usuario ASPNET ubicada en: C:\Documents and Settings\NET\ASPNET\Mis documentos

La última, estoy controlando la cantidad de visitantes con una variable de Aplicación. Utiliza para esto el archivo Global.asax.

Suerte y A SEGUIR DESARROLLANDO

Ing. Fernando Luque Sánchez
De Trujillo - Perú para el mundo


Espacios de nombres usados en el código de este artículo:

System.Data
System.Data.SQLClient
System.XML
System.Environment
System.IO


Fichero con el código de ejemplo: FernandoLuque_ASPyXML02.zip - (22) KB

(MD5 checksum: 72D4A5E37A9B37F70ED165CD1190C70A)


ir al índice principal del Guille