400 Chapter 8 • Using XML in the .NET Framework
Transforming an XML Document into Another XML Document
Suppose that our company has received an order from a customer in XML format.The XML file, named OrderA.xml, is shown in Figure 8.44.The file is also available in the accompanying CD.
Figure 8.44 An Order Received from a Customer in XML Format (OrderA.xml)
<?xml version="1.0" ?>
<!— Chapter 8\OrderA.XML —>
<Order>
<Agent>Alfred Bishop</Agent> <Item>50 GPM Pump</Item> <Quantity>10</Quantity> <Date>
<Month>8</Month>
<Day>24</Day>
<Year>2001</Year>
</Date>
<Customer>Pepsi Beagle</Customer> </Order>
Now we want to transmit a purchase order to our supplier to fulfill the previous order. Suppose that the XML format of our purchase order is different from that of our client as shown in Figure 8.45.The OrderB.xml file is also available in the accompanying CD.
Figure 8.45 The Purchase Order to Be Sent to the Supplier in XML Format (OrderB.xml)
<?xml version="1.0" encoding="utf-8"?>
<Order>
<Date>2001/8/24</Date>
<Customer>Company A</Customer>
<Item>
<Sku>P 25-16:3</Sku>
Continued
Using XML in the .NET Framework • Chapter 8 |
401 |
Figure 8.45 Continued
<Description>50 GPM Pump</Description>
<Quantity>10</Quantity>
</Item>
</Order>
The objective of this example is to automatically transform OrderA.xml (Figure 8.44) to OrderB.xml (Figure 8.45).The outputs of this application are shown in Figures 8.46 and 8.47.
Figure 8.46 Transformation of an XML Document to Another XML Document
Figure 8.47 The Target XML File as Displayed in Internet Explorer
We have developed an XSLT file (shown in Figure 8.48) to achieve the necessary transformation. In the XSLT code, we have used multiple templates.The
402 Chapter 8 • Using XML in the .NET Framework
complete listing of the XSLT code is shown in Figure 8.48.The code is also available in the order.xsl file in the accompanying CD.
Figure 8.48 Complete Listing of order.xsl
<?xml version="1.0" ?>
<!— Chapter 8\order.xsl —>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<Order>
<Date>
<xsl:value-of select="/Order/Date/Year" />/ <xsl:value-of select="/Order/Date/Month" />/ <xsl:value-of select="/Order/Date/Day" />
</Date>
<Customer>Company A</Customer> <Item>
<xsl:apply-templates select="/Order/Item" />
<Quantity><xsl:value-of select="/Order/Quantity"/></Quantity>
</Item>
</Order>
</xsl:template>
<xsl:template match="Item">
<Sku>
<xsl:choose>
<xsl:when test=". ='50 GPM Pump'">P 25-16:3</xsl:when> <xsl:when test=". ='100 GPM Pump'">P 35-12:5</xsl:when> <!—other Sku would go here—>
<xsl:otherwise>00</xsl:otherwise>
</xsl:choose>
</Sku>
<Description>
<xsl:value-of select="." />
</Description>
Continued
Using XML in the .NET Framework • Chapter 8 |
403 |
Figure 8.48 Continued
</xsl:template>
</xsl:stylesheet>
Subsequently, we have developed the XSLT2.aspx file to employ the XSLT code in the order.xsl file to transform the OrderA.xml to OrderB.xml.The complete listing of the .aspx file is shown in Figure 8.49.This code is also available in the accompanying CD.The transformation is performed in the ShowTransformed() subprocedure of our .aspx file. In this code, the Transform method of an XSLTransform object is used to transform and generate the target XML file.
Figure 8.49 Complete Listing for XSLT2.aspx
<!—Chapter8/XSLT2.aspx—>
<%@ Page Language="VB" Debug="True"%> <%@ Import Namespace="System.Xml"%>
<%@ Import Namespace="System.Xml.XPath"%> <%@ Import Namespace="System.Xml.Xsl"%> <%@Import Namespace="System.IO"%>
<html><head></head><body><form runat="server"> <b>XSL Transformation Example </b><br/> <asp:ListBox id="lstInitial" runat="server" rows="9"
width=250/>
<asp:ListBox id="lstFinal" runat="server" rows="9" width=250/><br/><br/> <br/><br/>
<asp:Button id="cmdTransform" Text="Transform the XML" runat="server" onClick="showTransformed" />
<asp:Button id="cmdDisplayTgt" Text="Show Transformed XML in IE" runat="server" onClick="showTarget" />
</form></body></html>
<Script Language="vb" runat="server">
Sub Page_Load(sender As Object, e As EventArgs)
If Not Page.IsPostBack Then
Dim myDoc As New XPathDocument(Server.MapPath("OrderA.xml"))
Continued
404 Chapter 8 • Using XML in the .NET Framework
Figure 8.49 Continued
Dim myNav As XPath.XPathNavigator
Dim myIterator As XPath.XPathNodeIterator ' Set nav object
myNav = myDoc.CreateNavigator()
' Iterate through all the attributes of the descendants myIterator =myNav.Select("/Order") myIterator=myNav.SelectDescendants(XPathNodeType.Element,false) myIterator.MoveNext()
While myIterator.MoveNext()
' Add the Items to the DropdownList lstInitial.Items.Add _
(myIterator.Current.Name+" :"+myIterator.Current.Value) End While
End If
End Sub
Sub showTransformed(sender As Object,e As EventArgs)
' Load the XML Document
Dim myDoc As New XPathDocument(Server.MapPath("OrderA.xml"))
' Declare the XSLTransform Object
Dim myXsltDoc As New XSLTransform
' Create the filestream to write a XML file
Dim myfileStream As New FileStream _
(Server.MapPath ("OrderB.xml"),FileMode.Create,FileShare.ReadWrite)
' Load the XSL file
myXsltDoc.Load(Server.MapPath("order.xsl"))
' Tranform the XML file according to XSL Document
myXsltDoc.Transform(myDoc,Nothing,myfileStream)
myfileStream.Close()
lstFinal.Items.Clear
Dim myDoc2 As New XPathDocument(Server.MapPath("OrderB.xml")) Dim myNav As XPath.XPathNavigator
Dim myIterator As XPath.XPathNodeIterator ' Set nav object
Continued
www.syngress.com
Using XML in the .NET Framework • Chapter 8 |
405 |
Figure 8.49 Continued
myNav = myDoc2.CreateNavigator()
' Iterate through all the attributes of the descendants myIterator =myNav.Select("/Order") myIterator=myNav.SelectDescendants(XPathNodeType.Element,false) myIterator.MoveNext()
While myIterator.MoveNext()
' Add the Items to the DropdownList lstFinal.Items.Add _
(myIterator.Current.Name+" :"+myIterator.Current.Value) End While
End Sub
Sub showTarget(sender As Object,e As EventArgs)
Response.Redirect(Server.MapPath("OrderB.xml"))
End Sub </Script>
Working with XML and Databases
Databases are used to store and manage organization’s data. However, it is not a simple task to transfer data from the database to a remote client or to a business partner, especially when we do not clearly know how the client will use the sent data.Well, we may send the required data using XML documents.That way, the data container is independent of the client’s platform.The databases and other related data stores are here to stay, and XML will not replace these data stores. However, XML will undoubtedly provide a common medium for exchanging data among sources and destinations. It will also allow various software to exchange data among themselves. In this context, the XML forms a bridge between ADO.NET and other applications. Since XML is integrated in the
.NET Framework, the data transfer using XML is lot easier than it is in other software development environments. Data can be exchanged from one source to another via XML.The ADO.NET Framework is essentially based on Datasets, which, in turn, relies heavily on XML architecture.The DataSet class has a rich collection of methods that are related to processing XML. Some of the widely used ones are ReadXml,WriteXml, GetXml, GetXmlSchema, InferXmlSchema, ReadXmlSchema, and WriteXmlSchema.
406 Chapter 8 • Using XML in the .NET Framework
In this context, we will provide two simple examples. In the first example, we will create a DataSet from a SQL query, and write its contents as an XML document. In the second example, we will read back the XML document generated in the first example and load a DataSet. What are the prospective uses of these examples? Well, suppose that we need to send the products data of our fishing products to a client. In earlier days, we would have sent the data as a text file. But in the .NET environment, we can instead develop a XML document very fast by running a query, and subsequently send the XML document to our client.What is the advantage? It is fast, easy, self-defined, and technology independent.The client may use any technology (like VB, Java, Oracle, etc.) to parse the XML document and subsequently develop applications. On the other hand, if we receive an XML document from our partners, we may as well apply XML.NET to develop our own applications.
Creating an XML Document from a Database Query
In this section, we will populate a DataSet with the results of a query to the Products table of SQL Server 7.0 Northwind database. On the click event of a command button, we will write the XML file and its schema. (The output of the example is shown in Figure 8.50).We have developed the application in an .aspx file named DataSet1.aspx.The complete listing of the .aspx file is shown in Figure 8.51.The file is also available in the accompanying CD.
Figure 8.50 Output of DataSet1.aspx Application
The XML file created by the application is as follows:
<myXMLProduct>
Using XML in the .NET Framework • Chapter 8 |
407 |
<dtProducts>
<ProductID>13</ProductID>
<ProductName>Konbu</ProductName>
<UnitPrice>6</UnitPrice>
</dtProducts>
------ ---
------ ---
</myXMLProduct>
The code for the illustration is straightforward.The DataSet’s WriteXml and WriteXmlSchema methods were used to accomplish the desired task.
Figure 8.51 Complete Listing DataSet1.aspx
<!— Chapter8\DataSet1.aspx —>
<%@ Page Language = "VB" Debug ="True" %> <%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data.SqlClient" %> <html><head></head><body><form runat="server"> <b>Cheap Products:</b> <br/><br/>
<asp:DataGrid id="myGrid" runat="server"/><br/><br/>
<asp:Button id="cmdWriteXML" Text="Create XML File" runat="server" onclick="writeXML"/>
</body></form></html>
<Script Language="vb" runat="server">
Sub Page_Load(s As Object, e As EventArgs)
If Not Page.IsPostBack Then
Dim myDataSet As New DataSet("myXMLProduct")
Dim myConn As New _
SqlConnection("server=ora07;uid=sa;pwd=ahmed;database=Northwind") Dim mydataAdapter As New SqlDataAdapter _
("SELECT ProductID,ProductName,UnitPrice FROM Products WHERE
UnitPrice <7.00",myConn)
mydataAdapter.Fill(myDataSet,"dtProducts")
myGrid.DataSource=myDataSet.Tables(0)
Continued
408 Chapter 8 • Using XML in the .NET Framework
Figure 8.51 Continued
myGrid.DataBind
Session("sessDs")=myDataSet
End If
End Sub
Sub writeXML(s As Object, e As EventArgs)
Dim myFs1 As New FileStream _
(Server.MapPath _ ("myXMLData.xml"),FileMode.Create,FileShare.ReadWrite)
Dim myFs2 As New FileStream(Server.MapPath _ ("myXMLData.xsd"),FileMode.Create,FileShare.ReadWrite)
Dim myDataSet As New DataSet _ myDataSet=Session("sessDs")
' Use the WriteXml method of DataSet object to write an XML file ' from the DataSet
myDataSet.WriteXml(myFs1)
myFs1.Close()
myDataSet.WriteXmlSchema(myFs2)
myFs2.Close()
End Sub </Script>
Reading an XML Document into a DataSet
Here, we will read back the XML file created in the previous example (as shown in Figure 8.50) and populate a DataSet in the Page_Load event of our .aspx file. We will use the ReadXml method of the DataSet object to accomplish this objective.The output of the application is shown in Figure 8.52.The application has been developed in an .aspx file named DataSet2.aspx.The complete code for this application is shown in Figure 8.53.The code is also available in the accompanying CD.The code is self-explanatory.
Using XML in the .NET Framework • Chapter 8 |
409 |
Figure 8.52 Output of DataSet2.aspx Application
Figure 8.53 Complete Listing of DataSet2.aspx
<!— Chapter8\DataSet2.aspx —>
<%@ Page Language = "VB" Debug ="True" %> <%@ Import Namespace="System.Xml" %>
<%@ Import Namespace="System.Data" %> <%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Data.SqlClient" %> <html><head></head><body><form runat="server"> <b>Products Data From XML File:</b> <br/><br/> <asp:DataGrid id="myGrid" runat="server"/><br/><br/> </body></form></html>
<Script Language="vb" runat="server">
Sub Page_Load(s As Object, e As EventArgs)
If Not Page.IsPostBack Then
Dim myDataSet As New DataSet("myXMLProduct")
Dim myFs As New FileStream _
(Server.MapPath("myXMLData.xml"),FileMode.Open,FileShare.ReadWrite)
myDataSet.ReadXml(myFs)
myGrid.DataSource=myDataSet.Tables(0)
myGrid.DataBind
myFs.Close End If
End Sub </Script>