Inicio > asp.net > Usar xml/xslt para catálogo productos en web e-commerce

Usar xml/xslt para catálogo productos en web e-commerce

miércoles, 2 de febrero de 2011 Dejar un comentario Ir a comentarios

En los primeros usos de xml se mencionan bien para crear documentos validados con un dtd/schema o bien usarlo para tranportar datos entre diferentes sistemas.  En este segundo caso entra este ejemplo usado en la web elibros, para mantener catálogo de productos carrito de compra. Cuando creé esa aplicación, alrededor de 2002 en .net 1.1, usando la utilidad de simulación de carga de usuarios web stress tools, se obtenían mejores cifras para los usuarios concurrentes que podían acceder a la web usando xml y la posibilidad de cache que con acceso a la bb.dd sql server. Además posteriormente el haber usado xml facilitó el poder crear facturas en formato pdf, bastaba con recorer el xml. Pero lo mejor es verlo en el código usado.Empezamos con la parte de catálogo, tenemos la cabecera declarando el tiempo de cache, la inclusión de espacios de nombres a incluir y la conexión a la bb.dd. Como puede verse el fichero xml se crear como un stream.

<%@ Page Language="VB"%>
<%@ Outputcache Duration="86400" VaryByParam="none" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Text" %>
<%@Import Namespace="System.Xml.Xpath" %>
<%@Import Namespace="System.Xml" %>
<%@Import Namespace="System.Xml.Xsl" %>
<%@ Register TagPrefix="ctrldb" TagName="conecta" Src="conectadb.ascx" %>
<ctrldb:conecta id="ctlConnectStrings" runat="server"/>
<%-- usar esta función para en xml/xstl generar urls amigables
en el bucle que lee de la base datos crear un elemento con el titulo espacios cambiados por -
Dim TestString As String = "Shopping List"
' Returns "Shipping List".
Dim tituloenlace As String = Replace(Trim(mireader("Product_Name")), " ", "-")
en la hoja de estilo productos.xsl cambiar
<xsl:attribute name="href">/compra/additem<xsl:value-of select="ID"/>/<xsl:value-of select="TituloEnlace"/>.html --%>
....
....
<script language="VB"  runat="server">
sub Page_Load()
  dim strpathonly as string
  dim fichero, ficheroxsl as string
  dim strSqlpro as string
  dim strconn as string
  dim xmlstr as string
  dim objstream as stream
  dim objTransform As New XslTransform()
  strconn=ctlConnectStrings.SQLConnectionString
  strSqlpro="select * from product"
  strpathonly=Request.PhysicalPath
  fichero= Left(strpathonly, InStrRev(strpathonly, "")) & "productos.xml"
  ficheroxsl= Left(strpathonly, InStrRev(strpathonly, "")) & "productos.xsl"
  dim miconexion as SqlConnection = new sqlConnection(strconn)
  miconexion.Open()
  dim miSqlCommand as SqlCommand = new SqlCommand()
  miSqlCommand.Connection = miconexion
  miSqlCommand.CommandText =strSqlpro
  Dim mireader as SqlDataReader
  mireader=miSqlCommand.ExecuteReader()
  if not File.Exists(fichero) then

    xmlstr = "<?xml version=""1.0""?>" & vbCrLf
    xmlstr = xmlstr & "<Tienda>" & vbCrLf

 While mireader.Read()
	xmlstr = xmlstr & vbtab & "<Producto>" & vbcrlf & vbtab & vbtab  & "<Nombre>" & Trim(mireader("Product_Name")) & "</Nombre>" & vbcrlf & vbtab & vbtab & "<TituloEnlace>" & Replace(Trim(mireader("Product_Name")), " ", "-") & "</TituloEnlace>" & vbcrlf & vbtab & vbtab  & "<ID>" & Trim(mireader("product_id")) & "</ID>" & vbcrlf & vbtab & vbtab & "<producto_Descripcion>" & Trim(mireader("product_description")) & "</producto_Descripcion>" & vbcrlf
	xmlstr = xmlstr & vbtab & vbtab & "<Precio>" & FormatNumber(mireader("price"),2, , ,TriState.True) & "</Precio>" & vbcrlf & vbtab & vbtab & "<Descuento>" & FormatNumber(mireader("discount"),2, , ,TriState.True) & "</Descuento>" & vbcrlf  & vbtab & vbtab & vbCrLf
	xmlstr = xmlstr & vbtab &  "</Producto>" & vbCrLf

end While
xmlstr = xmlstr & vbtab & "</Tienda>" & vbcrlf
mireader.close()
miconexion.close()
objstream=File.OpenWrite(fichero)
dim xmlfi as new StreamWriter(objstream,System.Text.Encoding.unicode)
xmlfi.write(xmlstr)
xmlfi.close()
objTransform.Load(ficheroxsl)
dim objXPDoc as New XPathDocument(fichero)
dim writer As New XmlTextWriter(Response.Output)
objTransform.Transform(objXPDoc, Nothing, writer)
else
objTransform.Load(ficheroxsl)
dim objXPDoc as New XPathDocument(fichero)
dim writer As New XmlTextWriter(Response.OutputStream, System.Text.Encoding.utf8)
objTransform.Transform(objXPDoc, Nothing, writer)
end if
end sub
</script>

En principio como ya he comentado el interés de usar xml era la ventaja que daba para el número de usuarios que podía servir la aplicación. Pero una posterior modificación de la web para poder crear facturas en pdf mostró lo sencillo que era crearlas partiendo de tener los pedidos en xml. Para ello uso la librería ITextSharp

Imports System
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports iTextSharp.text
Imports iTextSharp.text.pdf

Partial Class ShowPDF
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        ShowTable()

    End Sub

    Sub ShowTable()

        Dim cartid As String
        If Not (Request.Cookies("cartid") Is Nothing) Then
            If (Request.Cookies("cartid").Value <> "") Then
                cartid = Request.Cookies("cartid").Value
            End If
        End If
        Dim fichxml As String
        fichxml = "cart" + cartid + ".xml"
        Dim fichpdf As String
        fichpdf = "fact" + cartid + ".pdf"
        Dim xpathdoc As XPathDocument = New XPathDocument(Server.MapPath(fichxml))
        Dim navigator As XPathNavigator = xpathdoc.CreateNavigator()
        Dim subnavigator As XPathNavigator = xpathdoc.CreateNavigator()
        Dim nodes As XPathNodeIterator = navigator.Select("/Cart/Producto")
        Dim subnode As XPathNodeIterator = subnavigator.Select("/Cart/Subtotal")
        Dim cabecera As String
        Dim subtotal As String
        Dim subxmldoc As XmlDocument = New XmlDocument
        subxmldoc.Load(Server.MapPath(fichxml))
        subtotal = "Total: " + subxmldoc.SelectSingleNode("/Cart/Subtotal").InnerText + " Euros"
        cabecera = "Elibros factura ref. " + cartid
        Dim doc As Document = New Document
        PdfWriter.GetInstance(doc, New FileStream(Request.PhysicalApplicationPath + fichpdf, FileMode.Create))
        doc.Open()
        Dim table As Table = New Table(6)
        table.BorderWidth = 1
        table.BorderColor = New Color(0, 0, 255)
        table.Padding = 3
        table.Spacing = 1
        Dim cell As Cell = New Cell(cabecera)
        cell.Header = True
        cell.Colspan = 6
        table.AddCell(cell)
        table.AddCell("ID Libro")
        table.AddCell("Título")
        table.AddCell("Detalle")
        table.AddCell("Precio €")
        table.AddCell("Cantidad")
        table.AddCell("Subtotal €")
        While (nodes.MoveNext())
            table.AddCell(nodes.Current.SelectSingleNode("ItemId").Value)
            table.AddCell(nodes.Current.SelectSingleNode("Nombre").Value)
            table.AddCell(nodes.Current.SelectSingleNode("producto_Descripcion").Value)
            table.AddCell(nodes.Current.SelectSingleNode("Precio").Value)
            table.AddCell(nodes.Current.SelectSingleNode("Cantidad").Value)
            table.AddCell(nodes.Current.SelectSingleNode("ItemSubTotal").Value)
        End While
        'subtotal = "Subtotal: " + subnode.Current.("Subtotal").Value
        Dim cellsub As Cell = New Cell(subtotal)
        cellsub.Colspan = 6
        table.AddCell(cellsub)
        doc.Add(table)
        doc.Close()
        Response.Redirect(fichpdf)
    End Sub

End Class

En este segundo caso se han usado expresiones xpath para el acceso a los elementos del fichero xml.

Categories: asp.net Tags: , , ,
  1. Sin comentarios aún.
  1. Sin trackbacks aún.
Debes estar registrado para dejar un comentario.