Working with MSXML 4.0 on the Server-Side with ASP.NET

only for RuBoard

You can continue using MSXML in the .NET Framework. If you already have much ASP code that uses the COM component MSXML, as you migrate to the .NET, you cannot afford to delete all your existing code only to forego all the learning, time, and resources you spent on it. If you are contemplating importing the code to ASP.NET, this section helps you do that by using the COM Interop services provided in .NET. Some new features in MSXML are also discussed.

Using the TlbImp.exe Utility to Import the MSXML Type Library into a .NET Application

.NET and COM components conform to different compiled standards. It is impossible to directly import a COM component into your .NET application and start using it. Microsoft provides a utility called TlbImp.exe with the .NET SDK, which aids in this process. This utility imports a COM type library into a proxy .NET assembly (called a Run-time Class Wrapper) that your .NET clients can reference through early binding. To run this utility from the command prompt, type the following:

  tlbimp msxml4.dll /out: Interop.MSXML2_4_0.dll  /namespace:MSXML2   /silent  

The first argument is the name of the COM type library, the /out argument specifies the name of the output file, assembly, and namespace in which to write the metadata definitions, the /namespace specifies the namespace in which to produce the assembly, and /silent suppresses the display of success messages.

You can examine the imported assembly with the MSIL Disassembler ( Ildasm.exe ) tool. The MSIL Disassembler tool provides a default GUI to view the metadata and disassembled code of any existing portable executable (PE) file in a hierarchical tree view. To use the GUI, type ildasm at the command line without supplying the PEfilename argument or any options. From the File menu, you can navigate to the PE file, the imported MSXML2_4_0.dll file in this case, to load Ildasm.exe . Figure 5.8 shows the imported assembly as viewed from the MSIL Disassembler tool.

Figure 5.8. Using the MSIL Disassembler tool to view the imported assembly.
graphics/05fig08.gif

Creating this wrapper by using Visual Studio .NET makes things much simpler. All you need to do is this:

  1. In the Add Reference window, select the COM tab and browse to Microsoft XML, v4.0 component.

  2. Select the v4.0 component and click OK.

The IDE creates a wrapper and copies it to the bin directory of your project. (See Figure 5.9.)

Figure 5.9. Using tlbimp.exe from Visual Studio .NET.
graphics/05fig09.gif

You can follow the same procedure to create a wrapper for your existing COM components using MSXML. The utility automatically creates the wrapper for MSXML, so you don't need to do it separately.

The saveXML.aspx Page

You can look into using ASP.NET and C# to produce more elegant code by using the WebControls and HTMLControls. You can save the XML data that was posted in the previous example to a file on the server hard disk. You will also see how you can perform XSL Transformation using MSXML. Listing 5.7 shows the webform that displays a message after saving the XML data and the data in the form of an HTML table. (Skip to Listing 5.9 to see the code behind this webform .)

Listing 5.7 Saving XML Data to the Disk and XSLT Transformation ( saveXML.aspx )
 <%@ Page language="c#" Codebehind="saveXML.aspx.cs" AutoEventWireup="false"            Inherits="CSMSXML.SaveXML" %>  <HTML>       <body>             <form id="Form1" Runat="server">                 <table>                      <tr>                           <td align="middle">                                <asp:Label ID="SaveMessage" Runat="server"  Font-Bold="True"></asp:Label>                           </td>                      </tr>                      <tr>                           <td>                                <div ID="tblCustomers" Runat="server">                                </div>                           </td>                      </tr>                      <tr>                           <td align="middle">                               <asp:Button Text="Reload" Runat="server"  id="Button1"></asp:Button>                           </td>                      </tr>                 </table>             </form>       </body>  </HTML> 

This aspx page creates the HTML interface using the Label and Button web controls and the DIV HTML controls.

Transformation

The HTMLControl tblCustomers in Listing 5.7 's webform contains the XML data that's transformed into an HTML table. We perform this transformation using an XSLT stylesheet, Customers.xslt , shown in Listing 5.8.

Listing 5.8 Stylesheet for Transforming XML to a HTML Table ( Customers.xslt )
 <?xml version="1.0" encoding="UTF-8" ?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">       <xsl:template match="/">             <xsl:apply-templates />       </xsl:template>       <xsl:template match="Customers">            <table border="1">                 <thead>                      <th>CustomerID</th>                      <th>Company Name</th>                      <th>Contact Name</th>                      <th>Contact Title</th>                 </thead>                 <tbody>                      <xsl:for-each select="Customer">                           <tr>                                <td>                                     <xsl:value-of select="@id" />                                </td>                                <td>                                     <xsl:value-of select="CompanyName" />                                </td>                                <xsl:apply-templates select="Contact" />                           </tr>                      </xsl:for-each>                 </tbody>            </table>       </xsl:template>       <xsl:template match="Contact">            <td>                 <xsl:value-of select="FirstName" />                 <xsl:text disable-output-escaping='yes'><![CDATA[&nbsp;]]></xsl:text>                 <xsl:value-of select="LastName" />            </td>            <td>                 <xsl:value-of select="Title" />            </td>       </xsl:template>  </xsl:stylesheet> 

The "Code Behind" Class in C#

In the code behind file saveXML.aspx.cs , you can see the class saveXML that does the job of saving the XML string data that was posted to the saveXML.aspx page from the editCustomers.htm page as the value of a hidden HTML form field named customerData . This XML string data is saved into the XML file customers1.xml that is created on the first request. This class also transforms the XML data into a HTML table by using XSL transformation and displays it within the HTMLControl named tblCustomers by setting the controls innerHTML property. Listing 5.9 shows the code behind the file saveXML.aspx.cs .

Note

This file is generated by the Visual Studio .NET with empty code when the corresponding webform saveXML.aspx is created.


Listing 5.9 The Code Behind saveXML.aspx.cs
 using System;  using MSXML2;  namespace CSMSXML  {      public class SaveXML : System.Web.UI.Page       {           private DOMDocument40  objXML = new DOMDocument40 ();            private DOMDocument40  objXSL = new DOMDocument40 ();            protected System.Web.UI.WebControls.Label SaveMessage;            protected System.Web.UI.HtmlControls.HtmlGenericControl tblCustomers;            protected System.Web.UI.WebControls.Button Button1;            public SaveXML()            {                Page.Init += new System.EventHandler(Page_Init);            }            private void Page_Load(object sender, System.EventArgs e)            {               string  xslPath = Server.MapPath(".") + "\customers.xslt" ;                string destXMLPath = Server.MapPath(".") + "\customers1.xml" ;                 objXML.async = false;                 if (! Page.IsPostBack )                 {                     objXML.loadXML( Request.Form.Get("customerData") );                      objXML.save( destXMLPath );                      SaveMessage.Text = "The updated Customers XML file was saved on the graphics/ccc.gif server";                 }                 else                 {                     objXML.load(destXMLPath);                      SaveMessage.Text = "The saved file was reloaded into DOM.";                 }                 objXSL.async = false;                 objXSL.load(xslPath);                 tblCustomers.InnerHtml = objXML.transformNode( objXSL );            }            private void Page_Init(object sender, EventArgs e)            {                InitializeComponent();            }            private void InitializeComponent()            {                this.Load += new System.EventHandler(this.Page_Load);            }       }  } 

Listing 5.9 uses the save method of the DOMDocument to save the loaded document to a new destination, the customers1.xml file . This method is an extension of DOM because, as mentioned earlier, DOM doesn't provide any specifications for the documents. Optionally, you can provide the Response object as a parameter to the save method to send the document back to the client browser. In the case of a postback, which can be generated by using the Reload button, the document is loaded from the newly created file.

This example also shows you how server-side transformation works with MSXML 4.0, which is close to compliance with the XSLT Recommendation. You load the XSLT in Listing 5.9 into another instance of the MSXML DOM. Then perform the transformation using the transformNode() method, which processes the Document node and its children using the supplied XSLT. This enables you to apply an XSL template without explicitly having to define the link within the XML document; thus leaving you the flexibility to have multiple XSLT files for the same XML and provide multiple views. Figure 5.10 shows the output from the aspx page.

Figure 5.10. Saving XML and server-side transformation in ASP.NET.
graphics/05fig10.gif

Caching Compiled Stylesheets Using IXMLDOMXSLTemplate and IXSLProcessor

In the last section's example, you saw the XSL transformation using the transformNode method. But this is not practical for enormous sites that require a large number of XSL transformations because the stylesheet must be compiled every time you call the transformNode() method. The IXMLDOMXSLTemplate and the IXSLProcessor interfaces solve this problem by enabling you to cache compiled stylesheets, as shown in Listing 5.10. Listing 5.10 shows the code for the webform XSLTemplate.aspx that displays the results of transformation and the code behind file XSLTemplate.aspx.cs that demonstrates the use of IXMLDOMXSLTemplate and IXSLProcessor .

Note

These two files are derived with small modifications from our preceding sample, saveXML.aspx and the code behind file saveXML.aspx.cs .


Listing 5.10 XSLTemplate.aspx
 <%@ Page language="c#" Codebehind="XSLTemplate.aspx.cs"  AutoEventWireup="false"  Inherits="CSMSXML.MyXSLTemplate" %>  <HTML>       <body>            <form id="Form1" Runat="server">                 <table>                      <tr>                          <td align="middle">                               <asp:label id="HeadingMessage" Runat="server" graphics/ccc.gif Font-Bold="True"></asp:label>                          </td>                          </tr>                     <tr>                          <td>                               <div id="tblCustomers" Runat="server">                               </div>                          </td>                     </tr>                 </table>            </form>       </body>  </HTML> 
Caching Compiled Stylesheets ( XSLTemplate.aspx.cs )
 using System;  using MSXML2;  namespace CSMSXML  {      public class MyXSLTemplate : System.Web.UI.Page       {           private FreeThreadedDOMDocument40  objXML = new FreeThreadedDOMDocument40 ();            private FreeThreadedDOMDocument40  objXSL = new FreeThreadedDOMDocument40 ();            private XSLTemplate40  objXSLTemplate ;            private IXSLProcessor  processor;            protected System.Web.UI.WebControls.Label HeadingMessage;            protected System.Web.UI.HtmlControls.HtmlGenericControl tblCustomers;            public MyXSLTemplate()            {                Page.Init += new System.EventHandler(Page_Init);            }            private void Page_Load(object sender, System.EventArgs e)            {                string  xslPath = Server.MapPath(".") + "\customers.xslt" ;                 string destXMLPath = Server.MapPath(".") + "\customers.xml" ;                 objXML.async = false;                 try                 {                     objXSLTemplate = (XSLTemplate40)Application.Get("custProcessor" );                      if( objXSLTemplate==null)                      {                          throw  new NullReferenceException() ;                      }                 }                 catch(     Exception  ) //InvalidCastException OR NullReferenceException                 {                     objXSLTemplate = CreateCachedXSL(xslPath);                 }                 processor = objXSLTemplate.createProcessor();                 objXML.load(destXMLPath);                 HeadingMessage.Text = "Caching compiled stylesheets using graphics/ccc.gif IXMLDOMXSLTemplate "                 + "and IXSLProcessor.";                 processor.input = objXML;                 processor.transform();                 tblCustomers.InnerHtml = processor.output.ToString() ;            }            private  XSLTemplate40  CreateCachedXSL(string  xslPath)            {                objXSL.async = false;                 objXSL.load(xslPath);                 objXSLTemplate = new XSLTemplate40 ();                 objXSLTemplate.stylesheet =  objXSL ;            //cache the template object into an Application variable for future use                 Application.Lock();                 Application.Add("custProcessor", objXSLTemplate );                 Application.UnLock();                 return objXSLTemplate;            }            private void Page_Init(object sender, EventArgs e)            {                InitializeComponent();            }            private void InitializeComponent()            {                this.Load += new System.EventHandler(this.Page_Load);            }       }  } 

The XSLTemplate is a free-threaded component that compiles stylesheets. We create an instance of the free-threaded version of the DOMDocument to load the XSLT and assign it to the stylesheet property of the XSLTemplate object. The template is created and stored in the Application object. To perform the transformation, obtain a template in the form of the XSL processor component by calling the createProcessor method on the template. Finally, before the call to the transform method, you must specify the input to the template as the target XML document loaded into another instance of the free-threaded version of DOMDocument .

Adding Objects and Params into a Stylesheet Using the addObject and addParam Method

MSXML 4.0 enables you to extend the capabilities of the XSLT language through custom script libraries and COM components or classes. You will add a class called Customer to the last example. This class supports a GetCompanyName method and a ContactFirstName property . Listing 5.11 shows you how you can make use of them in a transformation by using the appropriate namespace qualifier.

Listing 5.11 Stylesheet Using an Object ( custAddObject.xslt )
 <?xml version="1.0" encoding="UTF-8" ?>  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Customer="urn:Customer">       <xsl:output method="xml" indent="yes" />       <xsl:param name="id" />       <xsl:template match="/">            <xsl:element name="Customer">                 <xsl:attribute name="id">                      <xsl:value-of select="$id" />                 </xsl:attribute>                 <xsl:element name="CompanyName">                      <xsl:value-of select="Customer:GetCompanyName()" />                 </xsl:element>                 <xsl:element name="ContactFirstName">                      <xsl:value-of select="Customer:get-ContactFirstName()" />                 </xsl:element>            </xsl:element>       </xsl:template>  </xsl:stylesheet> 

The code behind file addObject.aspx.cs shows the class Customer , which represents the Customer object that is referenced by the namespace Customer in the XSLT file custAddObject.xslt . Also, this Customer class exposes the method GetCompanyName() and the property ContactFirstName that are being used in the XSLT file custAddObject.xslt . The rest of the code in this file is similar to the one shown in the XSLTemplate.aspx.cs file in Listing 5.10, except for the calls to the addObject() and the addParameter() methods on the object of type IXSLProcessor .

The Customer class represents the customer node in the DOM that corresponds to the ID passed to its constructor. Listing 5.12 shows the code for the addObject.aspx page followed by the code behind the file addObject.aspx.cs .

Listing 5.12 addObject.aspx
 <%@ Page language="c#" Codebehind="addObject.aspx.cs" AutoEventWireup="false"  Inherits="CSMSXML.addObject" %>  <HTML>       <body>            <form id="Form1" Runat="server">                 <table>                      <tr>                           <td align="middle">                                <asp:label id="HeadingMessage" Runat="server" graphics/ccc.gif Font-Bold="True"></asp:label>                           </td>                      </tr>                      <tr>                           <td>                                <div id="tblCustomers" Runat="server">                                </div>                           </td>                      </tr>                 </table>            </form>       </body>  </HTML> 
Adding Objects and Params ( addObject.aspx.cs )
 using System;  using MSXML2;  namespace CSMSXML  {      public class addObject : System.Web.UI.Page       {           private FreeThreadedDOMDocument40  objXML = new            FreeThreadedDOMDocument40 ();            private FreeThreadedDOMDocument40  objXSL = new            FreeThreadedDOMDocument40 ();            private XSLTemplate40  objXSLTemplate ;            private IXSLProcessor  processor;            protected System.Web.UI.WebControls.Label HeadingMessage;            protected System.Web.UI.HtmlControls.HtmlGenericControl            tblCustomers;            public addObject()            {                Page.Init += new System.EventHandler(Page_Init);            }            private void Page_Load(object sender, System.EventArgs e)            {              string  xslPath = Server.MapPath(".") + "\custAddObject.xslt" ;               string destXMLPath = Server.MapPath(".") + "\customers.xml" ;               objXML.async = false;               objXML.load(destXMLPath);               objXSL.async = false;                 objXSL.load(xslPath);                 objXSLTemplate = new XSLTemplate40 ();                 objXSLTemplate.stylesheet =  objXSL ;                 processor = objXSLTemplate.createProcessor();                 processor.input = objXML;                 Customer customer = new Customer("THEBI" ,objXML);                 processor.addParameter( "id" , "THEBI", "" );                 processor.addObject( customer, "urn:Customer");                 processor.transform();  HeadingMessage.Text = "Adding Objects and params Into a Stylesheet using the" +"addObject graphics/ccc.gif and addParam method.";                 tblCustomers.InnerHtml = Server.HtmlEncode(processor.output.ToString()) ;            }            private void Page_Init(object sender, EventArgs e)            {                InitializeComponent();            }            private void InitializeComponent()            {                this.Load += new System.EventHandler(this.Page_Load);            }  }       public class Customer       {           private string contactFirstName     ;            private string companyName     ;            public string ContactFirstName            {                get                 {                     return contactFirstName;                 }            }            public Customer(string customerID , FreeThreadedDOMDocument40objXML )            {                IXMLDOMNode custNode = objXML.documentElement.selectSingleNode(                     "/Customers/Customer[@id='" + customerID + "']"  );                companyName           = custNode.childNodes[0].text ;                contactFirstName = custNode.childNodes[1].firstChild.text     ;            }            public string GetCompanyName()            {                return companyName ;            }       }  } 

The code in Listing 5.12 also shows the parameter value being added through the addParameter method to the XSLT param named "id". The transformation outputs the following string to the browser:

 <?xml version="1.0" encoding="UTF-16"?>  <Customer  id="THEBI">       <CompanyName>The Big Cheese</CompanyName>       <ContactFirstName>Liz</ContactFirstName>  </Customer> 

The addParameter method can be called between transform calls (in asynchronous processing), and further processing will use the updated parameter. Added parameters are referenced by <xsl:param> within the stylesheet.

Selecting Nodes with XPath 1.0

Listing 5.6 showed you node searching using XSL query passed to the selectSingleNode method. XPath 1.0 offers a more flexible processing model as compared to its precursor XSL Patterns, which was first supported in MSXML 2.0. The most significant change in XPath is the location path , which consists of an axis that establishes a tree relationship between the context and the nodes selected by the query. MSXML 4.0 provides support for the legacy XSL Patterns syntax and XPath 1.0. To maintain backward compatibility with existing code, the default selection language is XSL Patterns.

To change the current selection language to XPath, set the SelectionLanguage property to XPath through the setProperty method that's available from the IXMLDOMDocument2 interface. To revert back to the XSL Patterns, reset the property value to XSLPatterns . You can read the SelectionLanguage property through the getProperty method. The IXMLDOMSelection interface represents the list of nodes that match a given XSL Pattern or XPath expression. Listing 5.13 shows a simple example for using IXMLDOMSelection to find the number of nodes that match a specified XPath expression with two different contexts.

Listing 5.13 Stylesheet for Transforming XML to a HTML Table ( DOMSelection.aspx )
 <%@ Page language="c#"    %>  <%@ Import Namespace = "MSXML2"   %>  <script language="c#" runat="server">  void Page_Load(Object Sender, EventArgs E)  { string  lf = "<BR>";  DOMDocument40  objXML = new DOMDocument40 ();  IXMLDOMSelection selection ;  string xmlPath = Server.MapPath(".") + "\customers.xml" ;  objXML.async = false;  objXML.load(xmlPath);  //default section for MSXML3 is "SDLPattern"  //XSLPattern is no longer supported in MSXML4  objXML.setProperty( "SelectionLanguage", "XPath" );  IXMLDOMNode rootNode =      objXML.documentElement;  selection = (IXMLDOMSelection) rootNode.selectNodes( "child::Customer/Contact/*");  Response.Write("Expression: " + selection.expr + lf );  //prints child::Customer/Contact/*  Response.Write( "Length with the root node: " + selection.length + lf);//prints 9  IXMLDOMNode custNode =      rootNode.childNodes[1];  IXMLDOMNode contactNode = custNode.selectSingleNode( "child::Contact/*");  IXMLDOMNode  context =     selection.matches( contactNode );  if( context == null) //false  {      Response.Write("contactNode is not contained in the selected collection."  + lf  );  }  else if (context.Equals( rootNode ) ) //true  {      Response.Write("contactNode is contained in the selected collection." + lf   );  }  selection.context = objXML ;  Response.Write( "Length with the  second customer node: " + selection.length + lf );// graphics/ccc.gif prints 0  }  </script> 

The specified context node might even come from a different document as long as it shares the same threading model as the document that created the selection object. The selectNodes method returns an object that implements both the IXMLDOMNodeList interface and the new IXMLDOMSelection interface. So, apart from traversing the node list like the IXMLDOMNodeList , the IXMLDOMSelection provides other useful methods such as peekNode (to peek at the current node), removeAll , removeNext (to remove nodes from the collection), and clone (to clone the entire collection).

ServerXMLHTTP

The IXMLHTTPRequest interface provides methods and properties to establish communication with remote HTTP servers. The XMLHTTP implementation was designed to work on the clients and not on a web server, which has higher scalability requirements. You can create the object of XMLHTTP and use it in a browser client with JavaScript:

 var objXMLHTTP = Server.CreateObject("MSXML2.XMLHTTP.4.0") 

The drawback to this implementation is that it was built around WinInet control and is not capable of handling multiple threads. This prevented it from being a scalable solution on the server-side when large numbers of requests must be serviced. When used from a page in the client browser, the requests to a web server other than the one the page is hosted on will perform poorly or give incorrect results. You might notice a similar problem with the load method of XMLDOMDocument as you attempt to load XML documents from other servers.

MSXML 4.0 provides another object, ServerXMLHTTP . This object is an implementation of the IServerXMLHTTPRequest interface that inherits from IXMLHTTPRequest and extends it with the following four new methods: getOption , setOption , waitForResponse , and setTimeouts .

The following C# code in the ServerXMLHTTP.aspx opens a connection to a HTTP server and displays the response as XML. This example sends a request to another page, GetCustXML.aspx , which is on the same server. (This can be a page on any other web server.)

 <%@ Page language="c#"    %>  <%@ Import Namespace = "MSXML2"   %>  <script language="c#" runat="server">  void Page_Load(Object Sender, EventArgs E)  {           string url =  "http://localhost/CSMSXML/GetCustXML.aspx?customerid=THEBI";            try            {                ServerXMLHTTP40   objXMLHTTP = new ServerXMLHTTP40 ();                 objXMLHTTP.open( "GET" , url , false , "" , "" );                 objXMLHTTP.send("");                 if( objXMLHTTP.status == 200)                 {                     Response.Write( ( (IXMLDOMNode ) objXMLHTTP.responseXML ).xml );                 }            }            catch( Exception exception)            {                     Response.Write("Error: " + exception.Message );            }  }  </script> 

The following code is for the GetCustXML.aspx page that receives the customerid as a query string, formats the customerid into XML, and writes it to the response stream:

 <%@ Page language="c#"  %>  <%  Response.ContentType = "text/xml";  Response.Write("<?xml version='1.0' encoding='utf-8' ?> ");  Response.Write("<Customers><CustomerID>"+  Request["customerid"]+"</CustomerID></ graphics/ccc.gif Customers>");  %> 

Running the ServerXMLHTTP.aspx page from the browser displays the following in the browser window:

 <?xml version="1.0" ?>  <Customers>    <CustomerID>THEBI</CustomerID>  </Customers> 

The following code line shows the syntax for the open method of the ServerXMLHTTP object:

 oServerXMLHTTPRequest.open(bstrMethod, bstrUrl, bAsync, bstrUser,  bstrPassword); 

bstrUser and bstrPassword are optional parameters of the open method and enable users to log on to web servers secured with basic authentication. The third varAsync parameter is similar to the async property of the DOMDocument object. The open method also enables you to post data to the target URL. This is required if you want to post data to an aspx page that will dynamically build an XML based on the submitted data. You might also want to post data to an XML template file that's kept on a SQL XML virtual directory of a SQL Server 2000.

The following code is for the ServerXMLHTTP_POST.aspx page that uses the POST method to send a request to the GetCustXML.aspx page:

 <%@ Page language="c#"    %>  <%@ Import Namespace = "MSXML2"   %>  <script language="c#" runat="server">  void Page_Load(Object Sender, EventArgs E)  {           string url = "http://localhost/CSMSXML/getCustXML.aspx? contname=Liz";            try            {             ServerXMLHTTP40   objXMLHTTP = new ServerXMLHTTP40 ();              objXMLHTTP.open("POST", url , false , "" , "" );              objXMLHTTP.setRequestHeader("Content-Type", "application/ graphics/ccc.gif x-www-form-urlencoded" );              objXMLHTTP.send("customerid=THEBI&count=2");              if( objXMLHTTP.status == 200)                {                Response.Write( ( (IXMLDOMNode ) objXMLHTTP.responseXML ).xml );              }            }            catch( Exception exception)            {                     Response.Write("Error: " + exception.Message );            }  }  </script> 

Running the ServerXMLHTTP_POST.aspx page from the browser produces the same result that the ServerXMLHTTP.aspx page produced.

 <?xml version="1.0" ?>  <Customers>    <CustomerID>THEBI</CustomerID>  </Customers> 

Another application area where ServerXMLHTTP is exploited is with building Simple Object Access Protocol (SOAP) clients, where you can use this object to send a SOAP request to a remote server and receive the SOAP response. The following code snippet shows sending a SOAP request to a web service and getting the SOAP body sent as part of the SOAP response into an XMLDOMNode object:

 objXMLHTTP.open("POST", "http://localhost/CSMSXML/SOAPListener.aspx" , false, "" , "" );    objXMLHTTP.setRequestHeader("SOAPAction","http://newriders.com/GetCustomerDetail" );    objXMLHTTP.setRequestHeader("Content-Type", "text/xml" );  .    objXMLHTTP.send(strSOAPRequest);    IXMLDOMDocument soapEnvelope = (IXMLDOMDocument) objXMLHTTP.responseXML;    IXMLDOMNode     soapBody  = soapEnvelope.selectSingleNode("//SOAP-ENV:Body"); 

The strSOAPRequest that's passed to the send() method contains the string that represents an XML SOAP request. SOAP requests are discussed in greater detail in Chapter 11, "Creating and Using ASP.NET Web Services." You can read the response data in a specific format by using one of the four following properties: responseBody , responseStream , responseText , and responseXML . The responseXML property that you saw in the previous code represents the response entity body as parsed by the MSXML Parser. The responseStream property represents the response entity body as Istream; this offers considerable performance benefits when moving data through the HTTP protocol.

Using the ServerHTTPRequest Property to Load XML Documents

The following code shows you how to load XML documents with the load method of XMLDOMDocument in a thread-safe manner:

 DOMDocument40  objXML = new DOMDocument40 ();  objXML.async = false;  objXML.setProperty ("ServerHTTPRequest", true);  objXML.load ("http://localhost/CSMSXML/customers.xml");  Response.ContentType = "text/xml";  Response.Write (objXML.xml); 

The code takes advantage of the ServerHTTPRequest property flag, which indicates that the parser needs to use the server-safe ServerXMLHTTP object instead of the DOMDocument object to synchronously load an XML document from a server.

Things You Need to Know Before You Work with ServerXMLHTTP

For cases where a proxy server exists, you must install and run the WinHTTP Proxy Configuration Utility ( Proxycfg.exe ) that enables you to configure WinHTTP to access HTTP and HTTPS servers through a proxy server. After installing and running the utility, restart IIS to get ServerXMLHTTP working.

ServerXMLHTTP support is only available on computers that have Microsoft Windows 2000 installed or have Microsoft Windows NT 4.0 with Microsoft Internet Explorer 5.01 (or later) installed. For Microsoft Windows 95 and Microsoft Windows 98, XMLHTTP is the only alternative and it is well suited for single- user desktop applications. XMLHTTP also offers some advantages, such as URL caching and auto-discovery of proxy settings support, that are available with WinInet. The ServerXMLHTTP component has a limitation: The maximum number of instances existing simultaneously within a single process must not exceed 5,460.

Benefits of Using DOM

Before we move on to discuss SAX2 implementation in the MSXML Parser, you must understand when you should choose the DOM API to parser XML in your applications. The following lists the benefits of using DOM:

  • Easy to understand object-based implementation ” The DOM represents the XML document as a set of interfaces defined by the W3C DOM Recommendation. These interfaces model the contents of the XML document structure. This allows the programmer to think of the document contents as objects and use the properties and invoke methods on the objects to work with the document.

  • Maps closely with XML Infoset ” XML Information Set (Infoset) is an abstract data set that describes the available information from an XML document. For many applications, this way of looking at an XML document is more useful than analyzing and interpreting XML syntax. The DOM API closely maps to this XML Infoset recommendation.

  • Better XSLT transformations and XPath filtering ” The DOM works better for XSL transformations where the source XML document is transformed based on the XSLT template applied. DOM allows complex XPath filtering and automatically retains complex data structures that hold context information. With SAX, you must devise mechanisms to retain the context information yourself.

  • Easy to modify and save XML ” The DOM enables you to create or modify a document in memory and save the changed document to the hard disk. SAX is preferred for reading, not editing, the documents.

  • Provides random access to data ” It is possible to move back and forth in the document and randomly move to any part or node of the DOM tree. You do not have to worry about maintaining the context information, which is required by SAX.

  • Easy to implement push model on top of pull model ” After you have the entire document loaded into memory, it's easy to invoke the events in the push interfaces as you navigate through the DOM tree from top to bottom. This builds a push layer on top of the pull model.

Drawbacks of Using DOM

The following lists the drawbacks of using DOM:

  • Loads entire document in memory ” A document loaded in memory by the DOM parser in the MSXML might take up one to four times its original size in RAM. This can lead to a performance bottleneck when you work with large documents of 2MB or more on a web server.

  • Different parser versions ” As the MSXML parser tries to keep pace with the latest W3C specifications, you will find newer parser versions. You might need to update your code that uses an earlier parser version to make it compatible to a newer version; some methods or properties depreciate after newer versions are released, or you might want to take advantage of some newly added features.

  • Not extensible ” The DOM implementations cannot be extended to provide new implementations. The DOM Level 2 Core is defined in terms of interfaces, not implementations . To provide some extensions to DOM, you must use interface inheritance with DOM interfaces. Mathematical Markup Language (MathML), Synchronized Multimedia Integration Language (SMIL), and Scalable Vector Graphics (SVG) are examples of specifications that define some DOM extensions. The interfaces they define are inherited from the interfaces in Core DOM.

only for RuBoard


XML and ASP. NET
XML and ASP.NET
ISBN: B000H2MXOM
EAN: N/A
Year: 2005
Pages: 184

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net