XmlDocument and XslTransform "-->
only for RuBoard |
In the same manner that you can point the DocumentSource and TransformSource properties of the Xml server control to XML and XSL/T files on your file system and render them in the browser, you can use the Document and Transform properties of the Xml server control to render XmlDocument and XslTransform classes in the browser. There are many reasons why you might need to do this, such as rendering dynamically generated, nonpersistent XML data (that is, XML data not persisted to the file system), or even rendering the results of a call to a Web service (see Chapter 14, "Exposing Data Through a Web Service," for more information on building and consuming Web services).
As I take you through the following examples, you will learn how to use the XmlDocument and XslTransform classes with the Xml server control. For simplicity in showing how this works, I will be using XML and XSL/T files persisted on the file system. You certainly are not limited to this use, but it will demonstrate how these properties work.
Listing 12.5 shows the users.xml file. This is a simple XML file representing usernames and passwords for an application.
Note
The users.xml file can be downloaded from the companion Web site (www.samspublishing.com).
01: <?xml version="1.0" standalone="yes"?> 02: <Users> 03: <User> 04: <Name>Doug Seven</Name> 05: <Email>doug.seven@dotnetjunkies.com</Email> 06: <Password>thisisafakepassword</Password> 07: </User> 08: <User> 09: <Name>Donny Mack</Name> 10: <Email>donny.mack@dotnetjunkies.com</Email> 11: <Password>soisthis</Password> 12: </User> 13: <User> 14: <Name>Eric Neff</Name> 15: <Email>eric.neff@codejunkies.net</Email> 16: <Password>thisonetoo</Password> 17: </User> 18: <User> 19: <Name>Lance Hayes</Name> 20: <Email>lance.hayes@codejunkies.net</Email> 21: <Password>thisoneisreal</Password> 22: </User> 23: </Users>
Along with the users.xml file, I have a users.xsl stylesheet, as seen in Listing 12.6.
Note
The users.xsl file can be downloaded from the companion Web site (www.samspublishing.com).
01: <xsl:stylesheet version='1.0' 02: xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 03: <xsl:template match="/"> 04: <table border="0" cellspacing="0" cellpadding="4"> 05: <tr> 06: <th class="header">Name</th> 07: <th class="header">E-Mail</th> 08: <th class="header">Password</th> 09: </tr> 10: <xsl:for-each select='Users/User'> 11: <tr> 12: <td class="value" nowrap="true"><xsl:value-of select='Name'/></td> 13: <td class="value" nowrap="true"><xsl:value-of select='Email'/></td> 14: <td class="value" nowrap="true"><xsl:value-of select='Password'/></td> 15: </tr> 16: </xsl:for-each> 17: </table> 18: </xsl:template> 19: </xsl:stylesheet>
The XmlDocument and XslTransform classes represent XML and XSL data. Among their properties and methods , each of these classes exposes a Load() method, which can be used to load an XML or an XSL/T file, respectively, persisted on the file system, or persisted on another system. This can occur, provided that the XML or XSL/T file is accessible via a URL. To load the XML and XSL/T files into instances of the XmlDocument and XslTransform classes, you can use the Server.MapPath() method. Listing 12.7 shows a Web Form that uses the XmlDocument and XslTransform classes to load the users.xml and users.xsl files, and render the XML data using the Xml server control.
Note
The XmlDocument class is part of the System.Xml namespace, whereas the XslTransform class is part of the System.Xml.Xsl namespace.
[VB] 01: <%@ Import Namespace="System.Xml" %> 02: <%@ Import Namespace="System.Xml.Xsl" %> 03: <script language="VB" runat=server> 04: Protected Sub Page_Load(Sender As Object, E As EventArgs) 05: Dim xmlDoc As XmlDocument = New XmlDocument() 06: xmlDoc.Load(Server.MapPath("users.xml")) 07: myXml.Document = xmlDoc 08: 09: Dim xslTrans As XslTransform = New XslTransform() 10: xslTrans.Load(Server.MapPath("users.xsl")) 11: myXml.Transform = xxslTrans 12: End Sub 13: </script> [C#] 01: <%@ Import Namespace="System.Xml" %> 02: <%@ Import Namespace="System.Xml.Xsl" %> 03: <script language="C#" runat=server> 04: protected void Page_Load(Object sender, EventArgs e){ 05: XmlDocument xmlDoc = new XmlDocument(); 06: xmlDoc.Load(Server.MapPath("users.xml")); 07: myXml.Document = xmlDoc; 08: 09: XslTransform xslTrans = new XslTransform(); 10: xslTrans.Load(Server.MapPath("users.xsl")); 11: myXml.Transform = xslTrans; 12: } 13: </script> [VB & C#] 14: <html> 15: <head> 16: <title>Programming Datadriven Web Apps - Chapter 12</title> 17: <style rel="stylesheet" type="text/css"> 18: H3 { font: bold 11pt Verdana, Arial, sans-serif;} 19: .label { font: bold 9pt Verdana, Arial, sans-serif;} 20: .header { font: bold 9pt Verdana, Arial, sans-serif; background-color:tan; color: black;} 21: .value { font: 8pt Verdana, Arial, sans-serif;} 22: </style> 23: </head> 24: <body> 25: <form runat="server"> 26: <H3>Current Users</H3> 27: <asp:xml id="myXml" runat="server" /> 28: </form> 29: </body> 30: </html>
In Listing 12.7, you create a Web Form that uses the XmlDocument and XslTransform classes to load the users.xml and users.xsl files and render the XML data using the Xml server control. On lines 1 and 2, you import the necessary namespaces to use the XmlDocument and XslTransform classes. You load the XML and XSL/T files the same way for each class. On line 5, you create a new instance of the XmlDocument class, and on line 6 you use the Load() method with Server.MapPath() to load the users.xml file into the class. On line 7, you set the Xml server control's Document property to the instance of the XmlDocument class into which you loaded the XML data ( xmlDoc ).
The same process is used for the XslTransform class, but you load the users.xsl file, and set it to the Xml server control's Transform property. Figure 12.3 shows the rendered page from Listing 12.7.
The XmlDataDocument class can be used to convert data in a DataSet to XML for display using the Xml server control. The XmlDataDocument class derives from the XmlDocument class, and is synchronized with the DataSet class. The XmlDataDocument constructor has an overloaded option that accepts a DataSet as a single argument. When the XmlDataDocument class is constructed with a populated DataSet , each row in each DataTable in the DataSet becomes an element in the XmlDocument , and the fields of each row become child elements. Listing 12.8 shows how to fill a DataSet with products from the Northwind database, and display the results using the Xml server control.
Warning
Netscape Navigator 4.x and prior do not have the ability to render raw XML files. The example in Listing 12.8 will not work in older Netscape browsers.
[VB] 01: <%@ Page ContentType="text/xml" %> 02: <%@ Import Namespace="System.Data" %> 03: <%@ Import Namespace="System.Data.SqlClient" %> 04: <%@ Import Namespace="System.Xml" %> 05: <script language="VB" runat=server> 06: Sub Page_Load(Sender as Object, E as EventArgs) 07: Dim myDataSet As New DataSet() 08: Dim myDataAdapter as New SqlDataAdapter("SELECT TOP 10 * FROM Products", "server=localhost;database=Northwind;uid=sa;pwd=;") 09: myDataAdapter.Fill(myDataSet, "Products") 10: myDataSet.DataSetName = "ProductList" 11: Dim xmlDoc as XmlDataDocument = New XmlDataDocument(myDataSet) 12: myXml.Document = xmlDoc 13: End Sub 14: </script> [C#] 01: <%@ Page ContentType="text/xml" %> 02: <%@ Import Namespace="System.Data" %> 03: <%@ Import Namespace="System.Data.SqlClient" %> 04: <%@ Import Namespace="System.Xml" %> 05: <script language="C#" runat=server> 06: protected void Page_Load(Object sender, EventArgs e){ 07: DataSet myDataSet = new DataSet(); 08: myDataSet.DataSetName = "NorthwindInfo"; 09: SqlDataAdapter myDataAdapter = new SqlDataAdapter("SELECT TOP 10 * FROM Products", "server=localhost;database=Northwind;uid=sa;pwd=;"); 10: myDataAdapter.Fill(myDataSet, "Products"); 11: XmlDataDocument xmlDoc = new XmlDataDocument(myDataSet); 12: myXml.Document = xmlDoc; 13: } 14: </script> [VB & C#] 15: <asp:xml id="myXml" runat="server" />
In Listing 12.8, you query the Northwind database for the first 10 products in the Products table using the Sql Managed Provider. After filling the DataSet , you create a new XmlData Document . On line 11, you use the overloaded constructor to create the XmlDataDocument based on the DataSet . This creates an XML document similar (if not identical) to the XML document in Listing 12.1. On line 12, you use the Xml server control's Document property to apply the XmlDataDocument to the Xml server control. The rendered output from Listing 12.8 is shown in Figure 12.4.
Because a DataSet can hold multiple DataTable s, the XmlDataDocument can be created with multiple element types. For example, if you were to fill the DataSet with the Products data in Listing 12.8, and then fill a new DataTable in the same DataSet with data from the Customers table, you could create an XmlDataDocument that had both Products and Customers elements. If you tie that together with an XSL/T stylesheet, you can do some interesting things. Listing 12.9 shows a revised version of the NorthwindInfo.xsl stylesheet, named NorthwindInfo2.xsl .
Note
The NorthwindInfo2.xsl file can be downloaded from the companion Web site (www.samspublishing.com).
01: <xsl:stylesheet version='1.0' 02: xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> 03: <xsl:template match="/"> 04: <style> 05: .title { font: bold 10pt Verdana, Arial; color: black;} 06: .description { font: 8pt Verdana, Arial;} 07: .header { font: bold 9pt Verdana, Arial; background-color:tan; color: black;} 08: .subheader { font: bold 8pt Arial; color: black;} 09: .value { font: 8pt Arial;} 10: </style> 11: <table border="0" cellspacing="0" cellpadding="4"> 12: <tr> 13: <th class="header">ID</th> 14: <th class="header">Product Name</th> 15: <th class="header">Qty/Unit</th> 16: <th class="header">Unit Price</th> 17: </tr> 18: <xsl:for-each select='NorthwindInfo/Products'> 19: <tr> 20: <td class="value" nowrap="true" align="center"> 21: <xsl:value-of select='ProductID'/></td> 22: <td class="value" nowrap="true"> 23: <xsl:value-of select='ProductName'/></td> 24: <td class="value" nowrap="true"> 25: <xsl:value-of select='QuantityPerUnit'/></td> 26: <td class="value" nowrap="true" align="right"> 27: $<xsl:value-of select='UnitPrice'/></td> 28: </tr> 29: </xsl:for-each> 30: </table> 31: <table border="0" cellspacing="0" cellpadding="4"> 32: <tr> 33: <th class="header">Customer ID</th> 34: <th class="header">Company Name</th> 35: <th class="header">Contact Name</th> 36: <th class="header">Phone</th> 37: <th class="header">Fax</th> 38: </tr> 39: <xsl:for-each select='NorthwindInfo/Customers'> 40: <tr> 41: <td class="value" nowrap="true" align="center"> 42: <xsl:value-of select='CustomerID'/></td> 43: <td class="value" nowrap="true"> 44: <xsl:value-of select='CompanyName'/></td> 45: <td class="value" nowrap="true"> 46: <xsl:value-of select='ContactName'/></td> 47: <td class="value" nowrap="true"> 48: <xsl:value-of select='Phone'/></td> 49: <td class="value" nowrap="true"> 50: <xsl:value-of select='Fax'/></td> 51: </tr> 52: </xsl:for-each> 53: </table> 54: </xsl:template> 55: </xsl:stylesheet>
The NorthwindInfo2.xsl file has two xsl:for-each functions to control the style of two different elements, Products and Customers . Listing 12.10 shows the code for a Web Form that queries the Northwind database and fills a DataSet with two DataTable s, Products and Customers . The DataSet then is passed into the overloaded XmlDataDocument constructor, before being assigned to the Xml server control. The NorthwindInfo2.xsl stylesheet is loaded into the XslTransform class and applied to the same Xml server control.
[VB] 01: <%@ Import Namespace="System.Data" %> 02: <%@ Import Namespace="System.Data.SqlClient" %> 03: <%@ Import Namespace="System.Xml" %> 04: <%@ Import Namespace="System.Xml.Xsl" %> 05: <script language="VB" runat="server"> 06: Sub Page_Load(Sender as Object, E as EventArgs) 07: Dim myDataSet As New DataSet() 08: myDataSet.DataSetName = "NorthwindInfo" 09: Dim myDataAdapter as New SqlDataAdapter("SELECT TOP 10 * FROM Products", "server=localhost;database=Northwind;uid=sa;pwd=;") 10: myDataAdapter.Fill(myDataSet, "Products") 11: myDataAdapter.SelectCommand.CommandText = "SELECT TOP 10 * FROM Customers" 12: myDataAdapter.Fill(myDataSet, "Customers") 13: Dim XmlDoc as XmlDataDocument = New XmlDataDocument(myDataSet) 14: Dim xslTrans As XslTransform = New XslTransform() 15: xslTrans.Load(Server.MapPath("NorthwindInfo2.xsl")) 16: myXml.Document = xmlDoc 17: myXml.Transform = xslTrans 18: End Sub 19: </script> [C#] 01: <%@ Import Namespace="System.Data" %> 02: <%@ Import Namespace="System.Data.SqlClient" %> 03: <%@ Import Namespace="System.Xml" %> 04: <%@ Import Namespace="System.Xml.Xsl" %> 05: <script language="C#" runat=server> 06: protected void Page_Load(Object sender, EventArgs e){ 07: DataSet myDataSet = new DataSet(); 08: myDataSet.DataSetName = "NorthwindInfo"; 09: SqlDataAdapter myDataAdapter = new SqlDataAdapter("SELECT TOP 10 * FROM Products", "server=localhost;database=Northwind;uid=sa;pwd=;"); 10: myDataAdapter.Fill(myDataSet, "Products"); 11: myDataAdapter.SelectCommand.CommandText = "SELECT TOP 10 * FROM Customers"; 12: myDataAdapter.Fill(myDataSet, "Customers"); 13: XmlDataDocument xmlDoc = new XmlDataDocument(myDataSet); 14: XslTransform xslTrans = new XslTransform(); 15: xslTrans.Load(Server.MapPath("NorthwindInfo2.xsl")); 16: myXml.Document = xmlDoc; 17: myXml.Transform = xslTrans; 18: } 19: </script> [VB & C#] 20: <html> 21: <body> 22: <form runat="server"> 23: <asp:xml id="myXml" runat="server" /> 24: </form> 25: </body> 26: </html>
In Listing 12.10, you create a Web Form that uses the Sql Managed Provider to run two queries on the Northwind database and fill the data into two DataTable s in a DataSet . On line 13 you create a new XmlDataDocument by passing the DataSet into the constructor. This creates an XML document with an element for each row in each DataTable . On lines 14 and 15, you create a new XslTransform object and load it with the NorthwindInfo2.xsl stylesheet. On lines 16 and 17, you set the Xml server control's Document and Transform properties to the XmlDataDocument and the XslTransform objects, respectively.
The XslTransform will apply the XSL/T stylesheet to the XML data. Because the XSL/T stylesheet has xsl:for-each loops for both the Products and Customers elements, two tables will be rendered to the page, one table of products, and one of customers. The rendered output from Listing 12.10 is seen in Figure 12.5.
only for RuBoard |