Xtensible Markup Language y Visual Basic .NET

[usando las clases SQLXML 3.0 administradas ]

 
Fecha: 09/Sep/2005 (07/09/2005)
Autor: Arbis Percy Reyes Paredes
Email: [email protected]
http://percyreyes.blogspot.com 

¡ Los peruanos Sí podemos !

Para esta vez he preparado este artículo respecto al manejo de XML con Visual Basic .NET, donde usted aprenderá a crear diversos esquemas anotados, documentos XML y manipularlos desde Visual Basic usando las clases XMLSQL 3.0 administradas, todo esto y mucho más se detallarán a continuación. Los temas a explicar son:
CLASES SQLXML ADMINISTRADAS 

Las clases SQLXML administradas permiten escribir programas Visual Basic .NET que apeovechen las características de la segunda y tercera versión web. Existen tres clases SQLXML administradas: SqlXmlCommand, SqlXmlParameter, SqlXmlAdapter. Estas clases se utilizan en los procedimientos Visual Basic .NET para crear objetos y poder controlarlos mediante código gracias a sus propiedades y eventos. Particularmente estoy usando la versión SQLXML 3.0 para este artículo, usted puede descargarlo desde el site de Microsoft.

SQLXML ofrece compatibilidad con XML para las bases de datos de SQL Server. Permite a los desarrolladores salvar el vacío entre XML y los datos relacionales. Puede crear una vista XML de sus datos relacionales y trabajar con ella como si fuese un archivo XML. Aunque las clases SQLXML administradas se utilizan desde los programas del entorno de trabajo .NET, no existe documentación sobre las clases en la ayuda de Visual Studio .NET ni en la ayuda de Visual Basic .NET. Por suerte existe la ayuda de la Web Release 3 que detalla las propiedades y métodos expuestos por las clases SQLXML administradas.

Clase SqlXmlCommand  Se crea un objeto SqlXmlCommand declarando la cadena de conexión del objeto como parte de una espresión co el operador New. Esta cadena de conexión debe indicar el proveedor de datos SqlOleDB así como las características ADO y ADO .NET clásicas de acceso a servidor, base de datos e identificación de seguridad. Por ejemplo

Dim cnnString As String = "Provider=SQLOLEDB; Server=localhost;" & _
"DataBase=Northwind; Integrated Security=SSPI"
Dim cmd As SqlXmlCommand = New Microsoft.data.SqlXml.SqlXmlCommand(cnnString)

 

NOTA Antes que se pueda utilizar cualquier clase administrada SQLXML, el módulo Visual Basic .NET debe tener una referencia al espacio de nombres Microsoft.data.SqlXml. Tras añadir una referencia a la solución, se debe añadir una sentencia Imports en cualquier módulo en que se utilice la clase administrada a menos que se desee preceder las referencias individuales a las entidades de clase con el identificador del espacio de nombres Microsoft.data.SqlXml. 

Métodos de SqlXmlCommand Puede realizar una sentencia SQL contra una base de datos SQL Server y devolver el resultado en formato XML. Pôr ejemplo, el método ExecuteStream genera el conjunto de resultados de una sentencia SQL y crea un nuevo objeto Stream del conjunto de resultados en formatos XML. Antes de poder trabajar con el contenido de un objeto Stream, normalmente se le pasa a un lector y el lector le pasa sus resultados a un documento XML que puede ver o procesar caracteres de texto.

Se puede utilizar el método ExecuteToStream de un objeto SqlXmlCommand para pasar su conjunto de resultados a un objeto Stream existente en lugar de crear un nuevo Stream. También, se puede utilizar un objeto SqlXmlCommand para devolver un objeto XmlReader con el método ExecuteXmlReader. Un objeto XmlReader es un elemento de espacio de nombres System.Xml. Los procedimientos que utilizan objetos XmlReader obtienen un acceso rápido, sin colocarse en caché y sólo hacia delante sobre un flujo de datos que contiene XML. El método ExecuteNonQuery resulta adecuado paa comandos que no devuelven ningún conjunto de resultados, tales como los DiffGram.

Los métodos CreateParameters permiten añadir un parámetro a un objeto  SqlXmlCommand de modo quese puedan definir los valores en tiempo de ejecución. Si se quiere volver a utilizar un objeto SqlXmlCommand con otros parámetros o sin parámetros, llame al método ClearParameters para eliminar cualquier parámetro existente.

Propiedades de SqlXmlCommand el siguiente enumerado CommandType indica todos los posibles orígenes de un objeto SqlXmlCommand.

SqlXmlCommandType.Sql indica que el comando especifica un origen SQL, tal como una sentencia SELECT con una cláusula FOR XML, como comando.

SqlXmlCommandType.XPath resulta apropiado cuando se designa un comando de consulta con una expresión XPath.

SqlXmlCommandType.TemplateFile permite la ejecución de un archivo de plantilla, con sintaxis Sql o XPath, cuyo nombre se define en la propiedad CommandText.

SqlXmlCommandType.Template permite que el comando ejecute el contenido de un archivo de plantilla, con sintaxis Sql o XPath, cuyo nombre se define en la propiedad CommandStream.

SqlXmlCommandType.Updategram especifica un objeto Updategram de un comando a ejecutar.

SqlXmlCommandType.Diffgram desigan un Diffgram como argumento del comando.

Se utiliza la propiedad CommandText para declarar el origen del objeto SqlXmlCommand.

Clase SqlXmlParameter Los objetos SqlXmlcommand pueden tener parámetros dependientes jerárquicamente representados mediante objetos SqlXmlParameter. Usando el método CreateParameter de un SqlXmlCommand podemos crear un parámetro, asignándole  valores a las propiedades Name (nos da la posibilidad de hacer referencia al parámetro) y Value (permite asignar un valor a un parámetro en tiempo de ejecución) del parámetro.

Clase SqlXmlAdapter Estos objetos a un propósito similar a los objetos SqlDataAdapter del espacio de nombres System.Data.SqlClient. Tras declarar un variable como objeto SqlXmlAdapter, se puede crear la variable con una expresión que contenga el operador New de la clase SqlXmlAdapter. El objeto SqlXmlAdapter puede tomar como argumento una variable que apunte a un objeto SqlXmlCommand.

Los objetos SqlXmlAdapter tienen dos métodos, Fill y Update. Se utiliza el método Fill para rellenar un conjunto de datos. Se llama al método Update para insertar, modificar o borrar las filas del origen de datos al que apunta un objeto SqlXmlAdapter. En cualquier caso, todo lo que se debe hacer es definir un conjunto de datos como argummento. No se necesita designar una tabla específica del conjunto de datos.

Vayamos con un ejemplo donde se detalla como usar algunos de los objetos anteriormente explicados.

 Imports System.Data.SqlClient

 Public Class SaveDBQueryXmlToFile

    Shared Sub Main()
        'Creando la cadena de conexión
        Dim cnnString As String = "Provider=SQLOLEDB; Server=localhost;" & _
        "DataBase=Northwind; Integrated Security=SSPI"

        'creamos un objeto SqlXmlcommand
        Dim cmd As SqlXmlCommand = New Microsoft.data.SqlXml.SqlXmlCommand(cnnString)

        'definimos la raíz de nuestro documento XML
        cmd.RootTag = "Customers"

        'establecemos el tipo de sentencia como un origen SQL
        cmd.CommandType = SqlXmlCommandType.Sql

        'declaramos el origen del objeto SqlXmlCommand
        cmd.CommandText = "select customerid, companyname from Customers for xml auto"

        'creamos un objeto Stream para el XML a crear
        Dim MyFileStream As FileStream = New FileStream("C:\QueryXMLCustomers.xml", FileMode.Create)

         'ejecutamos la sentencia, y lo almacenamos en el objeto MyFileStream
        cmd.ExecuteToStream(MyFileStream)

         'cerramos el stream
        MyFileStream.Close()

         'inicializamo un proceso para mostrar los resultados
         Dim proceso As Process = New Process

         'visualizamos los resultados en nuestro explorador de internet.
        proceso.Start("IExplore.exe", "C:\QueryXMLCustomers.xml")

         'Emitimos un mensaje alertando la finalización 
        Console.WriteLine("proceso terminado...")

    End Sub

End Class

 

Creación de un documento XML con un esquema anotado

Los esquemas anotados permiten  que se defina el formato de un conjunto de resultados. Con el método normal  de especificar una cláusula FOR XML en una sentencia SELECT, los valores de columna de un conjunto de resultados siempre aparecen como atributos. La siguiente secuencia de comandos XML muestra un esquema anotado para la tabla Shippers. El esquema se llama SchemaShippers.xsd y debe estar colocado en la carpeta raíz de la solución. Para la gente que aún no se familiariza con los documentos XML, explicaré la estructura de este documento XML de prueba SchemaShippers.xsd.

El primer espacio de nombres apunta al sitio web del World Wide Consortium donde se encuentra la especificación del esquema XML. El segundo espacio de nombres apunta a un nombre de recursos universal de Microsoft (urn) para definir las relaciones o esquemas anotados.

El cuerpo del esquema comienza declarando un elemento llamado Shipper, este elemento contiene el atributo Sql:relation, que lo relaciona con un origen de datos llamado Shippers. Cuando una aplicación con una conexión a una base de datos Northwind hace referencia a este esquema, la aplicación puede extraer las filas de la tabla Shippers de acuerdo al formato del esquema. Este esquema define el formato de los valores de la columna ShipperID como atributo y CompanyName y Phone como elementos. El uso del elemento sequence especifica que el elemento CompanyName debe aparecer antes que el elemento CompanyName debe aparecer antes que el elemento Phone para cada distribuidor.

SchemaShippers.xsd

Vayamos detallando el código, para que usted entienda mejor.

Imports System.IO
Imports System.Xml
Imports Microsoft.Data.SqlXml
Imports System.Data.SqlClient

Module RunAnnotatedSchemaXPathQuery

    Public Sub Main()

        'Creando la cadena de conexión
        Dim cnnString As String = "Provider=SQLOLEDB; Server=localhost;" & _
        "DataBase=Northwind; Integrated Security=SSPI"

        'creamos un objeto SqlXmlcommand
        Dim cmd As SqlXmlCommand = New SqlXmlCommand(cnnString)

        'definiendo la etiqueta raíz del archivo XML
        cmd.RootTag = "Shippers"

        ' designa una consulta Path basada en un esquema anotado 
        ' utilizando el elemento Shipper del esquema SchemaShippers
        ' en el directorio superior al del archivo .exe de la aplicación.
        cmd.SchemaPath = "..\SchemaShippers.xsd"
        cmd.CommandType = SqlXmlCommandType.XPath
        cmd.CommandText = "Shipper"

        'creamos un objeto Stream para el XML a crear
        Dim MyXMLfile As String = New String("C:\MyShippersXML.xml")
        Dim MyFileStream As FileStream = New FileStream(MyXMLfile, FileMode.Create)

        'ejecutamos la sentencia, y lo almacenamos en el objeto MyFileStream
        cmd.ExecuteToStream(MyFileStream)

        'cerramos el stream
        MyFileStream.Close()

        'Emitimos un mensaje alertando la finalización  
        Console.WriteLine("proceso terminado...")

        'inicializamo un proceso para mostrar los resultados
        Dim proceso As Process = New Process

        'visualizamos los resultados en nuestro explorador de internet.
        proceso.Start("IExplore.exe", MyXMLfile)

    End Sub

End Module

Así se programó, pues así son los resultados:

Ejecución de una consulta XPath sobre un documento XML específico

Además de simplemente guardar un conjunto de resultados como un documento XML, se puede utilizar y consultar el documento directamente. Cuando se trabaja con un documento XML,  no se puede utilizar y consultar el documento mediante una sentencia SQL. En esta situación ideal para obtener un conjunto de resultados que cumplan algún criterio es XPath. Un ejemplo mejorará la comprensión de estas cosillas. Revise el siguiente código fuente

 

Imports System.IO
Imports System.Xml
Imports Microsoft.Data.SqlXml
Imports System.Data.SqlClient

Module RunXpathQueryWithArgumenForALocalDocument

    Public Sub Main()

        Dim cnnString As String = "Provider=SQLOLEDB; Server=localhost;" & _
        "DataBase=Northwind; Integrated Security=SSPI"

        Dim cmd As SqlXmlCommand = New SqlXmlCommand(cnnString)


        ' Designa el origen de datos cmd con el conjunto de resultados en formato XML.
        cmd.RootTag = "Productos" 'definición de la etiqueta raíz.
        cmd.CommandType = SqlXmlCommandType.Sql
        cmd.CommandText = "SELECT ProductID, ProductName, Discontinued FROM Products FOR XML AUTO"

            'Pasa el conjunto de resultados cmd a un XmlReader 
            'y carga un XmlDocument con el contenido de XmlReader
            Dim oXmlReader As XmlReader = cmd.ExecuteXmlReader
            Dim oXmlDocument As New XmlDocument
            oXmlDocument.Load(oXmlReader)
 
            
            'cierra el lector
            oXmlReader.Close()

            
            'Define una consulta XPath sobre los nodos del XmlDocument oXmlDocument
            'que tenga el valor 1 en Discontinued

            Dim oXmlNodeList As XmlNodeList = oXmlDocument.DocumentElement. _
            SelectNodes(""//Products [@Discontinued = 1]")

            'declara un nodo
            Dim oXmlnode As XmlNode
            ' 
            para cada nodo muestra un mensaje con su contenido
            'incluyendo las etiquetas XML
            Console.WriteLine("El número de registros del conjunto de resultado es " & _
            oXmlNodeList.Count.ToString & "." & vbCrLf)
            Dim out As String
            For Each oXmlnode In oXmlNodeList
                out = oXmlnode.OuterXml()
                Console.WriteLine(out)
            Next
            Console.ReadLine()
        End Sub
    End Module

Esto son los resultados:

Ejecución de consultas SQL Server parametrizadas

En muchas ocasiones las aplicaciones no pueden utilizar un documento XML como origen de datos porque necesitan los datos más recientes. En este caso, se puede ejecutar una consulta SQL Server parametrizada. El parámetro de la sentencia de consulta aún permite que los usuarios definan un conjunto de resultados para una consulta específica en tiempo de ejecución. Las clases SQLXML 3.0 facilitan este tipo de consultas.

El ejemplo RunSQLParameterQuery, comienza definiendo una cadena de conexión y creando un objeto SqlXmlCommand basado en la cadena. Después el ejemplo asigna valores a ciertas propiedades de SqlXmlCommand que define la consulta a ejecutar. Por ejemplo, la propiedad CommandText es una cadena SQL que designa un parámetro mediante un signo  de interrogación (?). Los usuarios pueden ejecutar el objeto SqlXmlCommand para devolver la información descrita en la lista de sentencia SELECT. El valor del parámetro Discontinued define el país para el que devuelve los resultados SqlXmlCommand. En el listado, el procedimiento escribe directamente el valor "1" en el parámetro Discontinued. La sintaxis para asignar el parámetro requiere la declaración de un objeto SqlXmlParameter, la llamada al método CreateParameter del objeto SqlXmlCommand y la sentencia de asignación de la propiedad Value del parámetro del objeto SqlXmlCommand.

El código del ejemplo de esta sección demuestra la aplicación de la clase.

Imports Microsoft.Data.SqlXml
Imports System.Xml
Imports System.IO
 

Module RunSQLParameterQuery

    Public Sub Main()

        ' establecemos la cadena de conexión.
        Dim cnnString As String = "Provider=SQLOLEDB; Server=localhost;" & _
        "DataBase=Northwind; Integrated Security=SSPI"

        ' creamos un objeto comando, pasánsole la cadena de conexión.
        Dim cmd As SqlXmlCommand = New SqlXmlCommand(cnnString)
        cmd.RootTag = "Productos" 'definición de la etiqueta raíz.
        cmd.CommandType = SqlXmlCommandType.Sql

        cmd.CommandText = "SELECT ProductID, ProductName, Discontinued FROM Products" & _
        " WHERE Discontinued= ? FOR XML AUTO"

            ' Crea un parámetro para cmd 
            Dim MyParameter As SqlXmlParameter
            MyParameter = (cmd.CreateParameter())

            ' y le asigna un valor
            MyParameter.Value = "1"

            ' declara e instancia un flujo de datos en memoria y lo rellena
            ' con el conjunto de resultados de cmd.

            Dim oMemoryStream As MemoryStream
            oMemoryStream = cmd.ExecuteStream

            ' copia el conjunto  de resultados del flujo 
            ' de datos a un lector para mostrar el contenido en la consola.
            Dim oStreamReader As New StreamReader(oMemoryStream)
            Console.WriteLine(oStreamReader.ReadToEnd)

            ' cerramos el objeto lector
            oStreamReader.Close()
            Console.ReadLine()

        End Sub



    End Module

Creo que por esta vez, esto a sido todo mi aporte. Recuerde que hay muchas funcionalidades respecto al tema que usted debe investigar. Tan sólo presenté algunos detalles con la finalidad de darles a conocer el manejo XML con Visual Basic .NET.

No olvide  de votar por este artículo en PanoramaBox.

FUENTE: PROGRAMACIÓN DE MICROSOFT SQL SERVER CON MICROSOFT VISUAL BASIC. NET - RICK DOBSON

Web Developer Percy Reyes Paredes

Saludos desde Trujillo  - Perú


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

System.IO
System.Xml 
Microsoft.Data.SqlXml
System.Data.SqlClient  
System.Data

ir al índice