Você está na página 1de 12

Applying XSLT to XML Using ASP.

NET 
(Page 1 of 5 )

This article explains the basics of XSL to transform XML documents using
simple examples. We will gradually focus on using ASP.NET to implement XSLT
for any XML document and even to database queries. It introduces different
ways of implementing XSL from browser’s perspective and server’s perspective.
We will also discuss some tips to generate automated XML from database
queries and then transform them to HTML using XSL transformations.

Introduction to XSL

Anyone who designs web pages using any tool/designer would certainly know
about what CSS is. We use HTML in combination with CSS to design and
present web pages in a more efficient manner. Basically a style sheet presents
a sheet of styles, which would affect certain tag(s) in a web document. By
modifying the underlying style sheets, sometimes the look and feel of entire
website gets changed dramatically.

As HTML is made up of standard pre-defined tags, we can simply design and


apply style sheets for necessary tags using CSS, and browser can understand
all those details very easily. But any XML document is generally designed using
user-defined tags (elements) to which browser may not understand all those
new tags (elements). Just like we use CSS to present HTML document in a
well-formatted and understandable manner, we use XSL to present (transform)
an XML document in any format we require.

XSL stands for eXtensible Stylesheet Language. It is a language used to design


and apply style sheets especially for XML documents. Originally the research
started to provide style sheet technology to XML using XSL, but finally ended
up with three more divisions of XSL. So, XSL now consists of three parts
namely XSLT, XPath and XSL-FO. XSLT is a language for transforming XML
documents (even today, several programmers call XSLT as XSL). XPath is a
language to filter, search or sort information available in XML documents. XSL-
FO is a language for formatting XML documents. In this article we mainly focus
on XSLT, which stands for XSL Transformations.

XSLT can also be used to transform an XML document to another XML


document (it need not be only HTML document). Another beauty of XSLT is
that it internally works/traverse using XPath language. We can even conclude
that “The better we learn about XPath, the better XSLT we can design”.
Although this article mainly focuses on XSL, I suggest you to go through the
fundamentals of XPath language for a better understanding (but not necessary
for this article).
Another important issue is that “not all the browsers can understand XSLT
technology”. Specifically old browsers like IE5, IE5.5, Netscape 4 etc, are not
compatible with XSL or XSLT files to the full-fledged recommendations of W3C.
They were developed on a working draft of W3C, which was not yet completed
by the time of their releases. IE6 or above and NN6 or above are completely
compatible with standard XSL(T) specifications recommended by W3C. But if
we use any server side programming to implement XSLT (like ASP.NET), we can
overcome the compatibility issues of any browser (as the transformation takes
place at server without browser’s knowledge). This issue is deeply examined in
the later part of this article.

Applying XSLT to XML Using ASP.NET - A Simple Example on XSLT 


(Page 2 of 5 )

Just to understand the structure of XSLT, let us test a small example on XSLT
using a simple XML document without using any server-side (ASP.NET) code.
This example can be directly executed by opening the XML document in any
XSLT supported browser (currently I tested with IE6).

So, let us start by creating a plain and simple XML document (sample1.xml) as
follows.

<?xml version="1.0" encoding="ISO-8859-1" ?>


<?xml-stylesheet type="text/xsl" href="sample1.xslt"?>
<Employees>
  <Employee>
    <Name>Stuart</Name>
    <Age>28</Age>
  </Employee>
</Employees>

Now we create an XSL style sheet (sample1.xslt) for the above XML document
as follows.

<?xml version="1.0" encoding="ISO-8859-1" ?>


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <b>Name of Employee : </b><xsl:value-of
select="Employees/Employee/Name" /><br/>
    <b>Age:</b><xsl:value-of select="Employees/Employee/Age" /><br/>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

Remember that the family of XML technologies are case sensitive. By this time,
if you open “sample1.xml” directly in IE6 or NN6, you should be able to see the
result something like the following:

Name of Employee: Stuart


Age: 28

If you observe the HTML source at browser, it would be something like the
following, which is nothing but the transformation applied through XSLT to the
XML document:

<html>
  <body>
    <b>Name of Employee : </b>Stuart<br>
    <b>Age:</b>28<br>
  </body>
</html>

Let us try to understand the above two files in detail now. “sample1.xml” is just
a simple XML document. “sample1.xslt” is our style sheet definition to
transform “sample1.xml”. If we carefully observe the sample1.xml file, we can
spot an interesting line:

<?xml-stylesheet type="text/xsl" href="sample1.xslt"?>

This is the only magic needed in any XML file to be transformed to any XSLT.
The above statement instructs browser to link the current XML document with
“sample1.xslt” and present (transform) it accordingly. So, in general we will not
see the XML document as a tree structure anymore. It will be presented
(transformed) in a different way as specified in “sample1.xslt”.

Now, let us study the most important lines in sample1.xslt.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

The above line defines that it is basically an XSLT document used for certain
transformation.

<xsl:template match="/">

The above line specifies the format (template) applicable to the root of XML
document. We can also specify individual templates for each and every XML
element as well. The attribute ‘match’ can be provided with any XPath
expression.

<xsl:value-of select="Employees/Employee/Name" />

And finally, the above line states that it has to get the value (text) present in
that path (Employees/Employee/Name) of XML document (tree) starting from
root. In this case it starts from root (/), then searches for Employees element
(first element), within that Employee child element (first child element) and
finally the child element Name (first child element) of Employee element. This
path could be replaced with any XPath expression.

The rest of the content should be easily understandable, as it mostly contains


XHTML elements to be transformed. Make sure that this example always takes
only the first elements into consideration. There is no use of placing more than
one employee information in sample1.xml file. We will overcome this drawback
in the later part of this article.

Applying XSLT to XML Using ASP.NET - XSLT with ASP.NET 


(Page 3 of 5 )

The above example works well with IE6 or other latest browsers (which support
XSLT), but what about the situation of old browsers? Our sample example
would never work on those browsers. To overcome this problem, we shift XML
and XSLT to the server side programming that supports these technologies.
One of them is ASP.NET. I further extend the previous sample example with
respect to ASP.NET using a simple web form with few lines of ASP.NET code.

Open your Visual Studio.NET and create a new ASP.NET project. Add the
above two files (sample1.xml and sample1.xslt) to the project. Drag an XML
control from toolbox on to the webform. Press F7 (code window) and copy the
following two statements at the top:

Imports System.Xml
Imports System.Xml.Xsl

Copy the following code in the page load event of that webform.

Dim docXML As New XmlDocument


      docXML.Load(Server.MapPath("sample1.xml"))
      Dim docXSL As New XslTransform
      docXSL.Load(Server.MapPath("sample1.xslt"))
      Xml1.Document = docXML
      Xml1.Transform = docXSL
I think the above code is self-explanatory. Basically, we are creating two objects
‘docXML’ (to hold an XML document) and ‘docXSL’ (to hold an XSL document).
Using the ‘Load’ method, we are loading the two files in to the respective
objects. We assign both of them to the XML server control (xml1) provided in
ASP.NET. The transformation gets implemented automatically at run-time
without any extra hurdle!!

Press F5 to execute the web application and you should be able to see the same
output to which you have seen earlier. By now, we designed a web application
using XML and XSLT, which is completely browser independent.

But, always designing static XML documents may not be helpful in all the
situations. What if I want to have a dynamically generated XML to be
transformed through XSLT? The next section addresses this issue in a very
pleasant manner.

Applying XSLT to XML Using ASP.NET - Query a Database and Transform


through XSLT using ASP.NET 
(Page 4 of 5 )

In this section, we will generate XML dynamically (using the ADO.NET related
XML architecture) for any query issued to a database, and finally transform it
based on a particular XSLT file. We will implement the same strategy as above,
but with little bit modifications to deal with database queries effectively.

Create a new ASP.NET project in VS.NET. Drag an XML control from toolbox on
to the webform. Press F7 (code window) and copy the following two statements
at the top:

Imports System.Xml
Imports System.Xml.Xsl

Add a new method to the class as following:

Private Function getXMLContent(ByVal SQL As String) As XmlDocument


    Dim ds As New DataSet("SQLData")
    Dim da As New SqlDataAdapter(SQL, "data source=.;initial
catalog=northwind;user id=sa")
    da.Fill(ds, "Rows")
    da.Dispose()
    Dim sw As New System.IO.StringWriter
    ds.WriteXml(sw)
    ds.Dispose()

    Dim docXML As New XmlDocument


    docXML.LoadXml(sw.ToString())
    sw.Close()
    Return docXML
  End Function

Don’t forget to make necessary modifications for the database connection


string to meet your requirements. Next, Copy the following code in the page
load event of the webform.

Dim docXML As XmlDocument = getXMLContent("select orderid,freight from


orders where orderid=11000")
    Dim docXSL As New XslTransform
    docXSL.Load(Server.MapPath("Format1.xslt"))
    Xml1.Document = docXML
    Xml1.Transform = docXSL

Add a new file ‘Format1.xslt’ to the current project and paste in the following
code:

<?xml version="1.0" encoding="ISO-8859-1" ?>


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
  <body>
    <table width="50%" cellspacing="0" cellpadding="0" style="font-
family:verdana;font-size:X-Small" border="1">
    <tr bgcolor="#336699"><th align="left"><font
color="White">OrderID</font></th><th align="right"><font
color="White">Freight</font></th></tr>
    <tr><td align="left"><xsl:value-of select="SQLData/Rows/orderid"
/></td><td align="right"><xsl:value-of select="SQLData/Rows/freight"
/></td></tr>
    </table>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

Press F5 to execute the web application and you should be able to see a table
with single row of information showing orderID and freight. I leave it to the
programmers to understand the above code, as it deals with very basics of
database programming and I/O in .NET.

Applying XSLT to XML Using ASP.NET - How to Transform More than One
Row? 
(Page 5 of 5 )
Till now we worked with only one record using XSLT. But what if we want more
than one record to be transformed using XSLT? This section addresses those
needs. We shall further enhance the example in previous section so that it can
transform more than one order from ‘orders’ table at a time.

In the example given in previous section, the SELECT retrieves only one row (as
it is filtered by orderID). We need to change it, so that it can retrieve more than
one row. Make the modification to the above statement as following:

Dim docXML As XmlDocument = getXMLContent("select top 10 orderid,freight


from orders ")

The above SELECT statement retrieves only first 10 orders (of course you can
give any query you require). Now, we need to make few more changes to
Format1.xslt file. Modify the Format1.xslt file so that it looks consistent with
the following code:

<?xml version="1.0" encoding="ISO-8859-1" ?>


<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
  <body>
    <table width="50%" cellspacing="0" cellpadding="0" style="font-
family:verdana;font-size:X-Small" border="1">
    <tr bgcolor="#336699"><th align="left"><font
color="White">OrderID</font></th><th align="right"><font
color="White">Freight</font></th></tr>
    <xsl:for-each select="SQLData/Rows">
    <tr><td align="left"><xsl:value-of select="orderid" /></td><td
align="right"><xsl:value-of select="freight" /></td></tr>
    </xsl:for-each>
    </table>
  </body>
</html>
</xsl:template>
</xsl:stylesheet>

Let us examine the modified code:

<xsl:for-each select="SQLData/Rows">
    <tr><td align="left"><xsl:value-of select="orderid" /></td><td
align="right"><xsl:value-of select="freight" /></td></tr>
    </xsl:for-each>
‘<xsl:for-each>’ element can be used to select every XML element of a specified
node set. It is quite similar to ‘for’ loop. As we are filtering to some extent using
‘<xsl:for-each>’ element, ‘<xsl:value-of>’ element should be given with more
specific information excluding the filtering.

Press F5 to execute the web application and you should be able to see a table
of 10 orders from database transformed using XSLT.

Closing Remarks

I suggest you to learn XPath language to design XSLT very effectively. As this
article mainly focuses on basics of XSLT, I could not give any information on
XPath. I examined these examples using Microsoft SQL Server 2000 Enterprise
Edition and Visual Studio.NET 2003 Enterprise Architect. But all the above
samples would definitely work with any database (provided you make
modifications to the .NET data provider). And it is not at all necessary to have
Visual Studio.NET to work with XSLT. You can also implement the in-line
approach of ASP.NET to get the things worked out. By designing XSLT with a
bit analysis, you can design templates for entire web site (for look and feel
compatibility). These templates could be reused for new web applications
without any hurdle. Complicated reports can also be designed using XSLT.

How to validate an XML file with an XSD file


Utlimately I want to be able to parse an xml STRING with an xsd STRING but
this is the best I could do: parsing an xml FILE with an xsd FILE. I basically
reworked a console application example in the MSDN help file into a nicer
lookingASP.NET Web form example. It tells you if your file is not well-formed
and then if it is not valid it lists out the specific reason (like in XMLSpy), quite
helpful to find an error in a large XML file as it returns the line number on
which the error occurred as well as the tag name. This was done in Visual
Studio .NET so to get it to work you will have to change the code around to
whatever you want to do. Notice that you have to have the namespace in the
root element of the XML file.
validate.aspx.cs
using System; 
using System.Collections; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Web; 
using System.Web.SessionState; 
using System.Web.UI; 
using System.Web.UI.WebControls; 
using System.Web.UI.HtmlControls; 
using System.IO; 
using System.Xml; 
using System.Xml.Schema; 

namespace validate 

   public class WebForm1 : System.Web.UI.Page 
   { 
       protected System.Web.UI.WebControls.Label Label1; 
       protected System.Web.UI.WebControls.Button Button1; 
       protected System.Web.UI.WebControls.Label Label3; 
       protected System.Web.UI.WebControls.Label TheXml; 
       protected System.Web.UI.WebControls.Label Label2; 
       protected System.Web.UI.WebControls.Label Output; 
       protected System.Web.UI.WebControls.Label Outcome; 
       protected System.Web.UI.WebControls.Label TheXsd; 
    
       private void Page_Load(object sender, System.EventArgs e) 
       { 
           //define variables 
           TheXml.Text = HttpContext.Current.Server.MapPath("books.xml"); 
           TheXsd.Text = HttpContext.Current.Server.MapPath("books.xsd"); 
           Outcome.Text = ""; 
       } 

       private void Button1_Click(object sender, System.EventArgs e) 


       { 
           //define variables 
           Outcome.Text = "<font color=\"green\">Succeeded</font>"; 
           Output.Text = ""; 

           //load schema 
           XmlSchemaCollection xsc = new XmlSchemaCollection(); 
           xsc.Add("generic", TheXsd.Text); 
           Validate(TheXml.Text, xsc); 
       } 

       private void Validate(String filename, XmlSchemaCollection xsc) 


       { 
           XmlTextReader reader = null; 
           XmlValidatingReader vreader = null; 

           reader = new XmlTextReader (filename); 


           vreader = new XmlValidatingReader (reader); 
           vreader.Schemas.Add(xsc); 
           vreader.ValidationEventHandler += new ValidationEventHandler
(ValidationCallBack); 
           try 
           { 
               while (vreader.Read()){} 
           } 
           catch 
           { 
               Output.Text = "XML Document is not well-formed."; 
           } 
           vreader.Close(); 
       } 

       public void ValidationCallBack (object sender, ValidationEventArgs args) 


       { 
           Outcome.Text = "<font color=\"red\">Failed:</font>"; 
           Output.Text += "Validation error: <font color=\"red\">" + args.Message
+ "</font><br>"; 
       }   

   } 
}

Books.xml
<?xml version="1.0"?> 
<bookstore xmlns="generic"> 
   <book genre="autobiography"> 
       <title>The Autobiography of Benjamin Franklin</title> 
       <author> 
           <first-name>Ben</first-name> 
           <last-name>Franklin</last-name> 
       </author> 
       <price>89.88</price> 
   </book> 
   <book genre="novel"> 
       <title>The Confidence Man</title> 
       <author> 
           <first-name>John</first-name> 
           <last-name>Melville</last-name> 
       </author> 
       <price>11.99</price> 
   </book> 
</bookstore> 

Books.xsd 
--------------------------- 
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="generic" elementFormDefault="qualified" targetNamespace="generic"> 
   <xsd:element name="bookstore" type="bookstoreType"/> 
   <xsd:complexType name="bookstoreType"> 
       <xsd:sequence maxOccurs="unbounded"> 
           <xsd:element name="book" type="bookType"/> 
       </xsd:sequence> 
   </xsd:complexType> 
   <xsd:complexType name="bookType"> 
       <xsd:sequence> 
           <xsd:element name="title" type="xsd:string"/> 
           <xsd:element name="author" type="authorName"/> 
           <xsd:element name="price" type="xsd:decimal"/> 
       </xsd:sequence> 
       <xsd:attribute name="genre" type="xsd:string"/> 
   </xsd:complexType> 
   <xsd:complexType name="authorName"> 
       <xsd:sequence> 
           <xsd:element name="first-name" type="xsd:string"/> 
           <xsd:element name="last-name" type="xsd:string"/> 
       </xsd:sequence> 
   </xsd:complexType> 
</xsd:schema> 

Você também pode gostar