<form id="hz9zz"></form>
  • <form id="hz9zz"></form>

      <nobr id="hz9zz"></nobr>

      <form id="hz9zz"></form>

    1. 明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

      用XML與ASP完成購物車

      [摘要]在線購物已經變得很平常了,而在使用購物車的時候,用戶期望在其身上能夠獲得(足夠的)靈活性?纯茨隳軌蛉绾伟袮SP和XML結合起來提供所用戶需要的功能。 創建虛擬購物車的方法從來都不是單一的。最近,我碰到一個機會重新編寫了一個經典的ASP購物車,讓它成為一個擁有與原來類似的外觀和感覺,但是更加...

          在線購物已經變得很平常了,而在使用購物車的時候,用戶期望在其身上能夠獲得(足夠的)靈活性。看看你能夠如何把ASP和XML結合起來提供所用戶需要的功能。

          創建虛擬購物車的方法從來都不是單一的。最近,我碰到一個機會重新編寫了一個經典的ASP購物車,讓它成為一個擁有與原來類似的外觀和感覺,但是更加靈活和更加快速的購物車。我決定利用XML,并開發一個跨瀏覽器的解決方案,F在讓我來告訴你我自己碰到的一些問題,以及我是如何改進原有設計的。

          原來的購物車
          由于原來的購物車是針對特定的一組客戶的,所以它更多地依賴于對用戶的培訓而非易用性。除了完全清空購物車,沒有其他的機制用來對(所購的)內容進行更改。如果你往購物車里放入了錯誤的東西或者錯誤的數量,你不得不從頭開始才能夠更正這一錯誤。

          而不為人知的是,原來的購物車再也無法變得更好。有限數量的行被顯示出來,而客戶會一頁一頁地翻閱購物車里的內容。這種方法的問題是,所有的東西都被保存在一個以ASP會話ID為基礎的表格里。當客戶瀏覽購物車內容的時候,就會進行一次查詢。此外,如果會話超時,購物車的內容將會一直保留在表格里,直到有人手動刪除它。

          新的方法
          我不想重復以前的錯誤,所以新的購物車將會基于XML會話而不會基于表格。這種方法有多個好處。首先,整個購物車以XML數據島(Data Island)的形式保存在客戶端上,如下面列表A所示。在進行簡單瀏覽的時候,這就不再需要對表格進行查詢了。但是用到了MozillaDSO()和xmlPage()函數。

      列表A

          <root>     
          <row>          
          <selected></selected>          
          <line>1</line>          
          <quantity>1</quantity>          
          <item>W01</item>          
          <description>Swept hilt rapier</description>        
          <weight>3.6</weight>          
          <unitprice>195.95</unitprice>     
          </row> 
          
          <row>          
          <selected></selected>          
          <line>2</line>          
          <quantity>2</quantity>          
          <item>W02</item>          
          <description>Hand-and-a-half sword</description>          
          <weight>5.8</weight>          
          <unitprice>250.95</unitprice>     
          </row>  
         
          <row>          
          <selected></selected>          
          <line>3</line>          
          <quantity>1</quantity>          
          <item>W03</item>          
          <description>Wood long bow</description>          
          <weight>2.7</weight>          
          <unitprice>190.00</unitprice>     
          </row>
           
          <row>          
          <selected></selected>          
          <line>4</line>          
          <quantity>1</quantity>          
          <item>W04</item>          
          <description>Wizard staff</description>          
          <weight>3.1</weight>          
          <unitprice>89.25</unitprice>     
          </row> 
          
          <row>          
          <selected></selected>          
          <line>5</line>          
          <quantity>1</quantity>          
          <item>C01</item>          
          <description>Gauntlets</description>         
          <weight>0.7</weight>          
          <unitprice>25.00</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>6</line>          
          <quantity>5</quantity>          
          <item>C02</item>          
          <description>Knee-high boots</description>          
          <weight>1.9</weight>          
          <unitprice>95.00</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>7</line>          
          <quantity>9</quantity>          
          <item>C04</item>          
          <description>Cloak</description>          
          <weight>1.0</weight>          
          <unitprice>125.00</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>8</line>          
          <quantity>22</quantity>          
          <item>C05</item>          
          <description>Orc repellent</description>          
          <weight>1.0</weight>          
          <unitprice>8.95</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>9</line>          
          <quantity>1</quantity>          
          <item>W05</item>          
          <description>Dwarf axe</description>          
          <weight>8.0</weight>          
          <unitprice>358.95</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>10</line>          
          <quantity>1</quantity>          
          <item>A01</item>          
          <description>Steel cap</description>          
          <weight>2.8</weight>          
          <unitprice>219.95</unitprice>     
          </row>   

          <row>          
          <selected></selected>          
          <line>11</line>          
          <quantity>1</quantity>          
          <item>A02</item>          
          <description>Chainmail shirt</description>          
          <weight>15.3</weight>          
          <unitprice>487.22</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>12</line>          
          <quantity>1</quantity>          
          <item>A03</item>          
          <description>Mithril shirt</description>          
          <weight>0.4</weight>          
          <unitprice>87236.03</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>13</line>          
          <quantity>1</quantity>          
          <item>W07</item>          
          <description>Elvish long sword</description>          
          <weight>1.9</weight>          
          <unitprice>794.99</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>14</line>          
          <quantity>1</quantity>         
          <item>W08</item>          
          <description>Elvish short sword</description>          
          <weight>0.8</weight>          
          <unitprice>435.99</unitprice>     
          </row>    

          <row>          
          <selected></selected>          
          <line>15</line>          
          <quantity>3</quantity>          
          <item>W09</item>          
          <description>Short sword</description>          
          <weight>1.5</weight>          
          <unitprice>89.95</unitprice>     
          </row>
          </root>

          列表B

          function update() {
            /* Function:      update
               Creation Date: May 5, 2003
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to apply bound Data

           Island  changes to the full Data Island.  This is

           accomplished by matching line numbers in both Data

           Islands.  Once this has been completed the full Data

           Island is sent to the server via XMLHTTP.

           Update Date:       Programmer:              Description:
            */


           var objXMLHTTP;

           //     XMLHTTP request object

           var reWork = new RegExp('internet explorer','gi');


           document.body.style.cursor = 'wait';     //     Set cursor


           for(var i=0;i < objPage.bound.getElementsByTagName('row').length;i++)

           for(var j=0;j < objPage.full.getElementsByTagName('row').length;j++)

           if(objPage.bound.getElementsByTagName('line').item(i).firstChild.nodeValue == objPage.full.getElementsByTagName('line').item(j).firstChild.nodeValue) {

           for(var k=0;k < objPage.bound.getElementsByTagName('row').item(i).childNodes.length;k++)

           if(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName != '#text')

           switch(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName.toLowerCase()) {

           case('quantity'):

           case('selected'):

           try {

           objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).firstChild.nodeValue =     objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.nodeValue;

           }

           catch(e) {

           try {

           objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).appendChild(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.cloneNode(true));

           }

           catch(e) { }

           }


           break;

           }

           break;

           }

           //     Send updates

           if(reWork.test(navigator.appName))

           objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');

           else

           objXMLHTTP = new XMLHttpRequest();

           objXMLHTTP.open('GET','xmlServer.asp',true);

           objXMLHTTP.setRequestHeader('content-type','text/xml');

           objXMLHTTP.onreadystatechange = function() {

           var reWork = new RegExp('internet explorer','gi');

           if(objXMLHTTP.readyState == 4) {

           if(reWork.test(navigator.appName))

           objPage.full.XMLDocument.loadXML(unescape(objXMLHTTP.responseText));

           else

           objPage.full.innerHTML = unescape(objXMLHTTP.responseText);

           //Handle empty page

           if(objPage.page() > objPage.pagecount())

           objPage.showPrevious();

           else

           objPage.showPage();

           // Display page info

           document.getElementById('currentpage').lastChild.nodeValue = objPage.page();

           document.getElementById('totalpages').lastChild.nodeValue = objPage.pagecount();

           document.body.style.cursor = 'auto';

           } }

           // IE work around

           try {

           objPage.full.innerHTML = objPage.full.XMLDocument.xml;

           }

           catch(e) { }

           if(reWork.test(navigator.appName))

           objXMLHTTP.setRequestHeader('request',escape(objPage.full.XMLDocument.xml));

           else

           objXMLHTTP.setRequestHeader('request',escape(objPage.full.innerHTML));

           objXMLHTTP.send(null);

           }

          在做進一步講解之前,我會在同一個句子里使用Mozilla和XMLHTTP。有書面的證據表明Mozilla支持XMLHTTP。盡管其句法與Internet Explorer所用的句法稍有不同,但這并不是JavaScript無法處理的東西。完整的客戶端解決方案見A,而ASP見下面的列表C。

          圖A

       

          列表C

      <html>

      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
      <title>New Page 2</title>
      </head>

      <body>

      <table cellPadding="0" width="100%" border="0" id="table1">
       <tr>
        <td class="subhead1">Listing C</td>
       </tr>
       <tr bgColor="#ff0000">
        <td height="1">
        <img height="1" src="http://builder.com.com/i/tr/spacer.gif" width="1"></td>
       </tr>
       <tr>
        <td height="5">
        <img height="5" src="http://builder.com.com/i/tr/spacer.gif" width="1"></td>
       </tr>
       <tr>
        <td>
        <%@ Language=JScript %>

       <%
           Response.Buffer = true;

           var strTitle = 'Honest Ed\'s Adventure Emporium';

           Session('shoppingcart') = '<root>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>1</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W01</item>';
           Session('shoppingcart') += '<description>Swept hilt rapier</description>';
           Session('shoppingcart') += '<weight>3.6</weight>';
           Session('shoppingcart') += '<unitprice>195.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>2</line>';
           Session('shoppingcart') += '<quantity>2</quantity>';
           Session('shoppingcart') += '<item>W02</item>';
          Session('shoppingcart') += '<description>Hand-and-a-half sword</description>';
           Session('shoppingcart') += '<weight>5.8</weight>';
           Session('shoppingcart') += '<unitprice>250.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>3</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W03</item>';
           Session('shoppingcart') += '<description>Wood long bow</description>';
           Session('shoppingcart') += '<weight>2.7</weight>';
           Session('shoppingcart') += '<unitprice>190.00</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>4</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W04</item>';
           Session('shoppingcart') += '<description>Wizard staff</description>';
           Session('shoppingcart') += '<weight>3.1</weight>';
           Session('shoppingcart') += '<unitprice>89.25</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
          Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>5</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>C01</item>';
           Session('shoppingcart') += '<description>Gauntlets</description>';
           Session('shoppingcart') += '<weight>0.7</weight>';
           Session('shoppingcart') += '<unitprice>25.00</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>6</line>';
           Session('shoppingcart') += '<quantity>5</quantity>';
           Session('shoppingcart') += '<item>C02</item>';
           Session('shoppingcart') += '<description>Knee-high boots</description>';
           Session('shoppingcart') += '<weight>1.9</weight>';
           Session('shoppingcart') += '<unitprice>95.00</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>7</line>';
           Session('shoppingcart') += '<quantity>9</quantity>';
           Session('shoppingcart') += '<item>C04</item>';
           Session('shoppingcart') += '<description>Cloak</description>';
           Session('shoppingcart') += '<weight>1.0</weight>';
           Session('shoppingcart') += '<unitprice>125.00</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
          Session('shoppingcart') += '<line>8</line>';
           Session('shoppingcart') += '<quantity>22</quantity>';
           Session('shoppingcart') += '<item>C05</item>';
           Session('shoppingcart') += '<description>Orc repellent</description>';
           Session('shoppingcart') += '<weight>1.0</weight>';
           Session('shoppingcart') += '<unitprice>8.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>9</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W05</item>';
           Session('shoppingcart') += '<description>Dwarf axe</description>';
           Session('shoppingcart') += '<weight>8.0</weight>';
           Session('shoppingcart') += '<unitprice>358.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>10</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>A01</item>';
           Session('shoppingcart') += '<description>Steel cap</description>';
           Session('shoppingcart') += '<weight>2.8</weight>';
           Session('shoppingcart') += '<unitprice>219.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>11</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>A02</item>';
           Session('shoppingcart') += '<description>Chainmail shirt</description>';
           Session('shoppingcart') += '<weight>15.3</weight>';
           Session('shoppingcart') += '<unitprice>487.22</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>12</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>A03</item>';
           Session('shoppingcart') += '<description>Mithril shirt</description>';
           Session('shoppingcart') += '<weight>0.4</weight>';
           Session('shoppingcart') += '<unitprice>87236.03</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>13</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W07</item>';
           Session('shoppingcart') += '<description>Elvish long sword</description>';
           Session('shoppingcart') += '<weight>1.9</weight>';
           Session('shoppingcart') += '<unitprice>794.99</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>14</line>';
           Session('shoppingcart') += '<quantity>1</quantity>';
           Session('shoppingcart') += '<item>W08</item>';
           Session('shoppingcart') += '<description>Elvish short sword</description>';
           Session('shoppingcart') += '<weight>0.8</weight>';
           Session('shoppingcart') += '<unitprice>435.99</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '<row>';
           Session('shoppingcart') += '<selected></selected>';
           Session('shoppingcart') += '<line>15</line>';
           Session('shoppingcart') += '<quantity>3</quantity>';
           Session('shoppingcart') += '<item>W09</item>';
           Session('shoppingcart') += '<description>Short sword</description>';
           Session('shoppingcart') += '<weight>1.5</weight>';
           Session('shoppingcart') += '<unitprice>89.95</unitprice>';
           Session('shoppingcart') += '</row>';
           Session('shoppingcart') += '</root>';


       %>

       <?xml version="1.0" encoding="UTF-8"?>

       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
        <head>
           <title><%=strTitle %></title>
          <style type="text/css">

       TD

       {
          FONT-SIZE: 9pt;
          FONT-FAMILY: Tahoma

       }

       XML

       {
        WIDTH: 0px;
        HEIGHT: 0px;
        DISPLAY: none;

       }
          </style>
          <script language="JavaScript">
            <!-- <![CDATA[

       function setEvents() {
        /* Function:      setEvents
           Creation Date: April 25, 2003
           Programmer:    Edmond Woychowsky
           Purpose:       The purpose of this function is to create an instance
                              of the xmlPage object, initialize the object and
                               perform page initialization.

           Update Date:       Programmer:              Description:
        */

           objPage = new xmlPage();                         //     Create instance

           for(var i=0;i < document.getElementsByTagName('input').length;i++)
                if(document.getElementsByTagName('input').item(i).getAttribute('type') == 'button') {
                     document.getElementsByTagName('input').item(i).style.height = '26px';
                     document.getElementsByTagName('input').item(i).style.width = '100px';

                     document.getElementsByTagName('input').item(i).onmouseover = new Function('this.style.color = \'#FF0000\'');
                     document.getElementsByTagName('input').item(i).onmouseout = new Function('this.style.color = \'#000000\'');
                }

                                                                  //     Establish relationships
           objPage.bound = document.getElementById('xmlWindow');
           objPage.full = document.getElementById('xmlFull');
           objPage.table = document.getElementById('boundTable');

           objPage.length(10);                                   //     Set page length
           objPage.showPage();                                   //     Show first page

                                                                  //     Display page info
           try {
                document.getElementById('currentpage').removeChild(document.getElementById('currentpage').firstChild);
                document.getElementById('totalpages').removeChild(document.getElementById('totalpages').firstChild);
           }
           catch(e) { }

           document.getElementById('currentpage').appendChild(document.createTextNode(objPage.page()));
           document.getElementById('totalpages').appendChild(document.createTextNode(objPage.pagecount()));

       }


       function update() {
        /* Function:      update
           Creation Date: May 5, 2003
           Programmer:    Edmond Woychowsky
           Purpose:       The purpose of this function is to apply bound Data
                              Island  changes to the full Data Island.  This is
                               accomplished by matching line numbers in both Data
                               Islands.  Once this has been completed the full Data
                               Island is sent to the server via XMLHTTP.

           Update Date:       Programmer:              Description:
        */

           var objXMLHTTP;                                   //     XMLHTTP request object
           var reWork = new RegExp('internet explorer','gi');

           document.body.style.cursor = 'wait';     //     Set cursor

           for(var i=0;i < objPage.bound.getElementsByTagName('row').length;i++)
                for(var j=0;j < objPage.full.getElementsByTagName('row').length;j++)
                     if(objPage.bound.getElementsByTagName('line').item(i).firstChild.nodeValue == objPage.full.getElementsByTagName('line').item(j).firstChild.nodeValue) {
                          for(var k=0;k < objPage.bound.getElementsByTagName('row').item(i).childNodes.length;k++)
                               if(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName != '#text')
                                    switch(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).nodeName.toLowerCase()) {
                                         case('quantity'):
                                         case('selected'):
                                              try {
                                                   objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).firstChild.nodeValue = objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.nodeValue;
                                              }
                                              catch(e) {
                                                   try {
                                                       objPage.full.getElementsByTagName('row').item(j).childNodes.item(k).appendChild(objPage.bound.getElementsByTagName('row').item(i).childNodes.item(k).firstChild.cloneNode(true));
                                                   }
                                                  catch(e) { }
                                              }

                                              break;
                                    }

                          break;
                     }

                                                                 //     Send updates
           if(reWork.test(navigator.appName))
                objXMLHTTP = new ActiveXObject('Microsoft.XMLHTTP');
           else
                objXMLHTTP = new XMLHttpRequest();

           objXMLHTTP.open('GET','xmlServer.asp',true);
           objXMLHTTP.setRequestHeader('content-type','text/xml');
        
           objXMLHTTP.onreadystatechange = function() {
                var reWork = new RegExp('internet explorer','gi');

                if(objXMLHTTP.readyState == 4) {
                     if(reWork.test(navigator.appName))
                          objPage.full.XMLDocument.loadXML(unescape(objXMLHTTP.responseText));
                     else
                          objPage.full.innerHTML = unescape(objXMLHTTP.responseText);

                                                                  //    Handle empty page
                     if(objPage.page() > objPage.pagecount())
                          objPage.showPrevious();
                     else
                          objPage.showPage();

                                                                  //     Display page info
                     document.getElementById('currentpage').lastChild.nodeValue = objPage.page();
                     document.getElementById('totalpages').lastChild.nodeValue = objPage.pagecount();

                     document.body.style.cursor = 'auto';
               }
           }

                                                                  //     IE work around
           try {
                objPage.full.innerHTML = objPage.full.XMLDocument.xml;
           }
           catch(e) { }

           if(reWork.test(navigator.appName))
                objXMLHTTP.setRequestHeader('request',escape(objPage.full.XMLDocument.xml));
             else
                objXMLHTTP.setRequestHeader('request',escape(objPage.full.innerHTML));
        
           objXMLHTTP.send(null);

       }


       function ieBusTable(objTable) {
        /* Function:      ieBusTable
           Creation Date: April 30, 2003
           Programmer:    Edmond Woychowsky
           Purpose:       The purpose of this function is to remove the garbage
                               that Microsoft Internet Explorer displays when a table's
                               cell contains null.  This porblem only applies to div
                               and span tags.

           Update Date:       Programmer:              Description:
        */

           var reWork = new RegExp('internet explorer','gi');

           if(reWork.test(navigator.appName))
                if(objTable.readyState == 'complete') {
                     for(var i=0;i < objTable.getElementsByTagName('div').length;i++)
                          if(objTable.getElementsByTagName('div').item(i).innerText.length == 0)
                               objTable.getElementsByTagName('div').item(i).innerText = ' ';

                     for(var i=0;i < objTable.getElementsByTagName('span').length;i++)
                          if(objTable.getElementsByTagName('span').item(i).innerText.length == 0)
                               objTable.getElementsByTagName('span').item(i).innerText = ' ';
                }

       }


       function xmlPage() {
        /* Function:      xmlPage
           Creation Date: April 25, 2003
           Programmer:    Edmond Woychowsky
           Purpose:       The purpose of this class is to define the cross-browser
                               (Mozill & IE) paging object.

           Update Date:       Programmer:              Description:
        */

                                                                  //     Variables
           var objCommonAncestor = null;                   //     datafld common ancestor
           var objInitialTable = null;
           var strBound = null;                              //     XML window data island
           var strXML = null;                                   //     XML full data island
          var strTable = null;                              //     Bound HTML/XHTML table
           var intAbsolutePosition = 0;                    //     Window item index
           var intPage = 1;                                   //     Logical page number
           var intLength = 15;                                   //     Logical page length
           var blnInitialize = false;                         //     Initialize binds

                                                                  //     Properties
           this.bound = null;                                   //     XML window data island
           this.full = null;                                   //     XML full data island
           this.table = null;                                   //     Bound HTML/XHTML table

                                                                 //     Methods
           this.length = m_length;                              //     Page length
           this.page = m_page;                                   //     Current page number
           this.pagecount = m_pageCount;                   //     Calculate page count
           this.recordcount = m_recordCount;               //     "ADO recordset" recordcount
           this.showPage = m_showPage;                         //     Show current page
           this.showFirst = m_showFirst;                   //     "ADO recordset" movefirst
           this.showLast = m_showLast;                         //     "ADO recordset" movelast
           this.showNext = m_showNext;                         //     "ADO recordset" movenext
           this.showPrevious = m_showPrevious;               //     "ADO recordset" moveprevious

           function m_showPage() {
                /* Function:          m_showPage
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:              The purpose of this function is to show the
                                         current page's information.  This is accomplished
                                         by cloning the applicable nodes from the "full"
                                        Data Island to the "bound" Data Island.

                   Update Date:       Programmer:              Description:
                   May 13, 2003            Edmond Woychowsky          Modified to invoke m_recordCount()
                                                                      to compute current record count.
                */

                var objRoot = document.createElement('root');
                var objXML = null;                              //     XML DOM for IE

                if(!blnInitialize)
                     initialize(this.bound,this.full,this.table);

                this.full = document.getElementById(strXML);
                this.bound = document.getElementById(strBound);

                                                                  //     Remove existing nodes
                try {
                     document.getElementById(strTable).innerHTML = objInitialTable.innerHTML;
                }
                catch(e) { }

                try {
                     for(var i=0;i < this.bound.childNodes.length;i++)
                          this.bound.removeChild(this.bound.childNodes.item(i));
                }
                catch(e) { }

                                                                  //     Add up to this.length nodes
                for(var i=intAbsolutePosition;i < (intAbsolutePosition + intLength);i++)
                     if(i > (m_recordCount() - 1))
                          break;
                     else {
                          try {                                   //     Unique Mozilla logic
                               objRoot.appendChild(this.full.getElementsByTagName(objCommonAncestor).item(i).cloneNode(true));
                          }
                          catch(e) {                              //     Unique IE logic
                               if(i == intAbsolutePosition) {
                                    objXML = new ActiveXObject('MSXML.DOMDocument');
                                    objRoot = objXML.createElement('root');
                               }

                               objRoot.appendChild(this.full.XMLDocument.getElementsByTagName(objCommonAncestor).item(i).cloneNode(true));
                         }
                     }

                this.bound.appendChild(objRoot);

                MozillaDSO();                                   //     Mozilla bind logic
           }

           function m_showFirst() {
                /* Function:          m_showFirst
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to show the
                                         first logical page.

                   Update Date:       Programmer:              Description:
                */

                intAbsolutePosition = 0;                    //     Set absolute position

                m_showPage();                                   //     Show page
           }

           function m_showLast() {
                /* Function:          m_showLast
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to show the
                                         last logical page.

                   Update Date:       Programmer:              Description:
                */

                intAbsolutePosition = (m_pageCount() - 1) * m_length();

                m_showPage();                                   //     Show page
           }

           function m_showNext() {
                /* Function:          m_showNext
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to show the
                                        next logical page.

                   Update Date:       Programmer:              Description:
                */

                if(m_page() < m_pageCount())
                     intAbsolutePosition += intLength;     //     Set absolute position

                m_showPage();                                   //     Show page
           }

           function m_showPrevious() {
                /* Function:          m_showPrevious
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                  Purpose:               The purpose of this function is to show the
                                         previous logical page.

                   Update Date:       Programmer:              Description:
                */

                if(m_page() > 1)
                    intAbsolutePosition -= intLength;     //     Set absolute position

                m_showPage();                                   //     Show page
           }

           function m_length() {
                /* Function:          m_length
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to set or get
                                         the logical page length.

                   Update Date:       Programmer:             Description:
                */

                if(arguments.length > 0)
                     intLength = parseInt(arguments[0],10);
                else
                     return intLength;
           }

           function m_page() {
                /* Function:          m_page
                  Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to compute the
                                         current logical page number.

                   Update Date:       Programmer:              Description:
                */

                return (parseInt((intAbsolutePosition / intLength),10) + 1);
           }

           function m_recordCount() {
                /* Function:          m_recordCount
                   Creation Date:     April 25, 2003
                   Programmer:          Edmond Woychowsky
                   Purpose:               The purpose of this function is to compute the
                                         return the total number of "records" in the
                                        "full" XML Data Island.

                   Update Date:       Programmer:              Description:
                   May 13, 2003            Edmond Woychowsky          Modified to recompute due
                                                                       to possible deletes.   
                */

                if(!blnInitialize)
                     initialize(this.bound,this.full,this.table);

                return document.getElementById(strXML).getElementsByTagName(objCommonAncestor).length;
           }

           function m_pageCount() {
                /* Function:          m_pageCount
                     Creation Date:     April 25, 2003
                     Programmer:          Edmond Woychowsky
                     Purpose:               The purpose of this function is to compute the
                                          return the total number of logical pages.
        
                     Update Date:       Programmer:              Description:
                     May 13, 2003            Edmond Woychowsky          Modified to invoke m_recordCount()
                                                                        to compute current record count.
                  */
        
                  if(!blnInitialize)
                       initialize(this.bound,this.full,this.table);
        
                  return parseInt((m_recordCount() + (intLength - 1)) / intLength,10);
             }
        
             function initialize(objBound,objXML,objTable) {
                  /* Function:          initialize
                     Creation Date:     April 25, 2003
                     Programmer:          Edmond Woychowsky
                     Purpose:               The purpose of this function is to perform the
                                           necessary housekeeping before paging can occur.
        
                     Update Date:       Programmer:              Description:
                  */
        
                  var objNodeName = new collection();
                  var arrNodeName;
        
                  switch(true) {
                       case((objBound == null) && (objXML == null) && (objTable == null)):
                            alert('Error: bound, xml and table not set.');
        
                            break;
                       case((objBound == null) && (objXML == null)):
                            alert('Error: bound and xml not set.');
        
                            break;
                       case((objBound == null) && (objTable == null)):
                            alert('Error: bound and table not set.');
        
                            break;
                       case((objXML == null) && (objTable == null)):
                            alert('Error: xml and table not set.');
        
                            break;
                       case(objBound == null):
                            alert('Error: bound not set.');
        
                           break;
                       case(objXML == null):
                            alert('Error: xml not set.');
        
                            break;
                       case(objTable == null):
                            alert('Error: table not set.');
        
                            break;
                      default:
                            for(var i=0;i < objTable.getElementsByTagName('input').length;i++)
                                 if(objTable.getElementsByTagName('input').item(i).getAttribute('datafld') != null)
                                      objNodeName.item(objTable.getElementsByTagName('input').item(i).getAttribute('datafld'),null);
        
                            for(var i=0;i < objTable.getElementsByTagName('div').length;i++)
                                 if(objTable.getElementsByTagName('div').item(i).getAttribute('datafld') != null)
                                      objNodeName.item(objTable.getElementsByTagName('div').item(i).getAttribute('datafld'),null);
        
                            for(var i=0;i < objTable.getElementsByTagName('span').length;i++)
                                if(objTable.getElementsByTagName('span').item(i).getAttribute('datafld') != null)
                                      objNodeName.item(objTable.getElementsByTagName('span').item(i).getAttribute('datafld'),null);
        
                            arrNodeName = objNodeName.keys();
                            objNodeName = new collection();
        
                            for(var i=0;i < arrNodeName.length;i++)
                                 objNodeName.item(objXML.getElementsByTagName(arrNodeName[i]).item(0).parentNode.nodeName,null);
        
                           if(objNodeName.keys().length != 1)
                                 alert('Error: unsupported XML document structure.');
                            else {
                                 objCommonAncestor = objNodeName.keys().join('');
        
                                 blnInitialize = true;
                            }
        
                                                                    //     Store node names
                            strBound = objBound.getAttribute('id');
                            strXML = objXML.getAttribute('id');
                            strTable = objTable.getAttribute('id');
        
                                                                    //     Store initial table
                            objInitialTable = objTable.cloneNode(true);
        
                            break;
                  }
             }
        }
        
        function MozillaDSO() {
          /* Function:      MozillaDSO
             Creation Date: April 16, 2003
             Programmer:    Edmond Woychowsky
             Purpose:       The purpose of this function is to perform binding of
                            XML Data Islands for Mozilla.  The logic herein is bypassed
                            for Microsoft Internet Explorer.
        
             Update Date:       Programmer:              Description:
          */
        
                                                         //  Global variables
          objXMLDI = new collection();                   //  XML data island collection
          objBound = new collection();                   //  Bound XHTML object collection
        
                                                         //  Local variables
          var objDatafld;                                //  Table datafld collection
          var objRow;                                    //  Table row
          var reWork = new RegExp('internet explorer','gi');
          var arrKeys = new Array();
          var intKey = 0;                                //  objBound collection key
          var intRows;                                   //  Row count
        
          if(!reWork.test(navigator.appName)) {
                                                         //  Locate data islands
            for(var i=0;i < document.getElementsByTagName('xml').length;i++)
              objXMLDI.add('#' + document.getElementsByTagName('xml').item(i).getAttribute('id'),document.getElementsByTagName('xml').item(i));
        
                                                         //  Locate bound nodes
            for(var i=0;i < document.getElementsByTagName('table').length;i++)
              if(document.getElementsByTagName('table').item(i).getAttribute('datasrc') != null) {
                objBound.add(intKey.toString(),new boundXML());
        
                objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('table').item(i).getAttribute('datasrc');
                objBound.item(intKey.toString()).node = document.getElementsByTagName('table').item(i);
                objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('table').item(i).nodeName;
        
                objDatafld = new collection();           //  Reset collection;
                intRows = 0;                             //  Reset row count
        
                                                         //  Remove all rows
                if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').length != 0) {
                  for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
                    objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j));
        
                    for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
                      objRow = objBound.item(intKey.toString()).node.lastChild.removeChild(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j));
                }
        
                                                         //  Determine bound nodes
                for(var j=0;j < objRow.getElementsByTagName('input').length;j++)
                  if(!objDatafld.exists(objRow.getElementsByTagName('input').item(j).getAttribute('datafld')))
                    objDatafld.item(objRow.getElementsByTagName('input').item(j).getAttribute('datafld'),null);
        
                for(var j=0;j < objRow.getElementsByTagName('div').length;j++)
                  if(!objDatafld.exists(objRow.getElementsByTagName('div').item(j).getAttribute('datafld')))
                    objDatafld.item(objRow.getElementsByTagName('div').item(j).getAttribute('datafld'),null);
        
                for(var j=0;j < objRow.getElementsByTagName('span').length;j++)
                  if(!objDatafld.exists(objRow.getElementsByTagName('span').item(j).getAttribute('datafld')))
                    objDatafld.item(objRow.getElementsByTagName('span').item(j).getAttribute('datafld'),null);
        
                arrKeys = objDatafld.keys();
        
                                                         //  Determine row count
                for(var j=0;j < arrKeys.length;j++)
                  if(intRows < objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length)
                    intRows = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(arrKeys[0]).length;
        
                for(var j=0;j < intRows;j++)
                  objBound.item(intKey.toString()).node.lastChild.appendChild(objRow.cloneNode(true));
        
                                                         //  Rebuild table and bind
                for(var j=0;j < objBound.item(intKey.toString()).node.getElementsByTagName('tr').length;j++)
                  for(var k=0;k < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').length;k++)
                    for(var l=0;l < objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.length;l++)
                      switch(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).nodeName.toLowerCase()) {
                        case('input'):
                              try {
                           if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox')
                              objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).value = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue;
                            else
                              objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).checked = eval(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue);
                          }
                          catch(e) { }
        
                          if(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('type') != 'checkbox')
                            objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').firstChild.nodeValue = this.value } catch(e) { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').appendChild(document.createTextNode(this.value)) };MozillaDSO;');
                          else
                            objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).onchange = new Function('try { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item(\'' + objBound.item(intKey.toString()).datasrc + '\').getElementsByTagName(\'' + objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld') + '\').item(' + j.toString() + ').appendChild(document.createTextNode(this.checked)) };MozillaDSO;');
        
                          break;
                        case('div'):
                       case('span'):
                          try {                        //  Text node exists
                            objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).firstChild.nodeValue = objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue;
                          }
                          catch(e) {                   //  Create text node
                            try {
                              objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).appendChild(document.createTextNode(objXMLDI.item(objBound.item(intKey.toString()).datasrc).getElementsByTagName(objBound.item(intKey.toString()).node.getElementsByTagName('tr').item(j).getElementsByTagName('td').item(k).childNodes.item(l).getAttribute('datafld')).item(j).firstChild.nodeValue));
                            }
                            catch(e) { }
                          }
        
                          break;
                      }
        
                      ++intKey;
              }
        
                                                         //  Non-tabular datasrc/datafld
              for(var i=0;i < document.getElementsByTagName('input').length;i++)
                if(document.getElementsByTagName('input').item(i).getAttribute('datafld') != null) {
                  objBound.add(intKey.toString(),new boundXML());
        
                  if(document.getElementsByTagName('input').item(i).getAttribute('datasrc') != null)
                    objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('input').item(i).getAttribute('datasrc');
        
                  objBound.item(intKey.toString()).datafld = document.getElementsByTagName('input').item(i).getAttribute('datafld');
                  objBound.item(intKey.toString()).node = document.getElementsByTagName('input').item(i);
                  objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('input').item(i).nodeName;
        
                  ++intKey;
                }
        
              for(var i=0;i < document.getElementsByTagName('div').length;i++)
                if(document.getElementsByTagName('div').item(i).getAttribute('datafld') != null) {
                  objBound.add(intKey.toString(),new boundXML());
        
                  if(document.getElementsByTagName('div').item(i).getAttribute('datasrc') != null)
                    objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('div').item(i).getAttribute('datasrc');
        
                  objBound.item(intKey.toString()).datafld = document.getElementsByTagName('div').item(i).getAttribute('datafld');
                  objBound.item(intKey.toString()).node = document.getElementsByTagName('div').item(i);
                  objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('div').item(i).nodeName;
        
                  ++intKey;
                }
        
              for(var i=0;i < document.getElementsByTagName('span').length;i++)
                if(document.getElementsByTagName('span').item(i).getAttribute('datafld') != null) {
                  objBound.add(intKey.toString(),new boundXML());
        
                  if(document.getElementsByTagName('span').item(i).getAttribute('datasrc') != null)
                    objBound.item(intKey.toString()).datasrc = document.getElementsByTagName('span').item(i).getAttribute('datasrc');
        
                  objBound.item(intKey.toString()).datafld = document.getElementsByTagName('span').item(i).getAttribute('datafld');
                  objBound.item(intKey.toString()).node = document.getElementsByTagName('span').item(i);
                  objBound.item(intKey.toString()).nodeName = document.getElementsByTagName('span').item(i).nodeName;
        
                  ++intKey;
                }
        
              arrKeys = objBound.keys();
        
                                                        //  Handle non-tabular binds
              for(var i=0;i < arrKeys.length;i++)
                switch(objBound.item(arrKeys[i]).nodeName.toLowerCase()) {
                  case('table'):
                    objBound.item(arrKeys[i]).rows = new Array();
        
                    break;
                  case('input'):
                    try {
                      if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') {
                        try {
                          if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox')
                            objBound.item(arrKeys[i]).node.value = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue;
                          else
                            objBound.item(arrKeys[i]).node.checked = eval(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue);
                        }
                        catch(e) { }
        
                            if(objBound.item(arrKeys[i]).node.getAttribute('type') != 'checkbox')
                          objBound.item(arrKeys[i]).node.onchange = new Function('try { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).firstChild.nodeValue = this.value } catch(e) { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).appendChild(document.createTextNode(this.value)) };MozillaDSO()');
                        else
                          objBound.item(arrKeys[i]).node.onclick = new Function('try { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).firstChild.nodeValue = this.checked } catch(e) { objXMLDI.item(this.getAttribute(\'datasrc\')).getElementsByTagName(this.getAttribute(\'datafld\')).item(0).appendChild(document.createTextNode(this.checked)) };MozillaDSO()');
                      }
                    }
                    catch(e) { }
        
                    break;
                  case('div'):
                  case('span'):
                    if(typeof(objBound.item(arrKeys[i]).datasrc) == 'string') {
                      try {                              //  Text node exists
                        objBound.item(arrKeys[i]).node.firstChild.nodeValue = objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue;
                      }
                      catch(e) {                         //  Create text node
                        try {
                          objBound.item(arrKeys[i]).node.appendChild(document.createTextNode(objXMLDI.item(objBound.item(arrKeys[i]).datasrc).getElementsByTagName(objBound.item(arrKeys[i]).datafld).item(0).firstChild.nodeValue));
                        }
                        catch(e) { }
                     }
                    }
        
                    break;
                  default:
                    alert('Error: Unsupported HTML Element - ' + objBound.item(arrKeys[i]).nodeName.toLowerCase());
        
                    break;
                }
            }
        
          function boundXML() {
            var datasrc = null;                          //  Data source (string)
            var datafld = null;                          //  Data field (string)
            var node = null;                             //  XHTML node (object)
            var nodeName = null;                         //  Node name (string)
          }
        }
        
        function collection() {
          /* Function:      collection
             Creation Date: August 16, 2002
             Programmer:    Edmond Woychowsky
             Purpose:       The purpose of this class is to define the collection
                            object associative array.
        
             Update Date:       Programmer:              Description:
          */
        
                                                         //  Properties
          this.objcollection = new Object;               //  Associative array
          this.count = 0;                               //  Total numbers of items
        
                                                         //  Methods
          this.add = colAdd;                             //  Add method
          this.exists = colExists;                       //  Exists method
          this.item = colItem;                          //  Item method
          this.removeAll = colRemoveAll;                 //  Remove all method
          this.remove = colRemove;                       //  Remove method
          this.keys = colKeys;                           //  Keys method
        
          function colAdd(strKey,strItem) {
            /* Function:      colAdd
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to add an item to
                              the collection object.
        
              Update Date:       Programmer:              Description:
            */
        
            if(typeof(this.objcollection[strKey]) == 'undefined')
              ++this.count;
        
              this.objcollection[strKey] = strItem;
          }
        
          function colExists(strKey) {
            /* Function:      colExists
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to return a boolean
                              indicating where or not a key exists in the
                              collection object.
        
               Update Date:       Programmer:              Description:
            */
        
            if(typeof(this.objcollection[strKey]) == 'undefined')
              return false;
            else
              return true;
          }
        
          function colItem(strKey,strItem) {
            /* Function:     colItem
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to either set or get
                              an item to or from the collection object.
        
               Update Date:       Programmer:              Description:
            */
        
            if(typeof(strItem) == 'undefined')
              return this.objcollection[strKey];
            else {
              if(typeof(this.objcollection[strKey]) == 'undefined')
                ++this.count;
        
              this.objcollection[strKey] = strItem;
            }
          }
        
          function colRemoveAll() {
            /* Function:      colRemoveAll
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to remove all keys
                              and items from the collection object and set the
                              item count to zero.
        
               Update Date:       Programmer:              Description:
            */
        
            this.objcollection = new Object;
            this.count = 0;
          }
        
          function colRemove(strKey) {
            /* Function:      colRemove
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to remove a single
                              item and it's associated key from the collection
                              object and decrement the count by one.
        
               Update Date:       Programmer:              Description:
            */
        
            if(typeof(strItem) != 'undefined') {
              this.objcollection[strKey] == 'undefined';
              --this.count;
            }
          }
        
          function colKeys() {
            /* Function:      colKeys
               Creation Date: August 16, 2002
               Programmer:    Edmond Woychowsky
               Purpose:       The purpose of this function is to return an array
                             consisting of the collection object's keys.
        
               Update Date:       Programmer:              Description:
            */
        
            var arrWork = new Array();
            var strKey;
        
            for(strKey in this.objcollection)
              if(this.objcollection[strKey] != 'undefined')
                arrWork.push(strKey);
        
            return arrWork;
          }
        }
        // ]]> -->
        </script>
        </head>
          <body onload="setEvents()">
             <table width="100%" border="0">
                  <tr>
                       <td width="100%" align="center" bgcolor="black" >
                           <font color="white" size="8pt"><%=strTitle %></font>
                       </td>
                  </tr>
             </table>
             <table width="100%" height="450" border="0">
               <tr>
                 <td align="left" valign="top">
                   <table id="boundTable" datasrc="#xmlWindow" width="100%" border="1" onreadystatechange="ieBusTable(this)">
                    <thead>
                      <td bgcolor="#FFFFEE" width="5%"><b>Delete</b></td>
                      <td bgcolor="#FFFFEE" width="5%"><b>Line</b></td>
                      <td bgcolor="#FFFFEE" width="20%"><b>Item number</b></td>
                      <td bgcolor="#FFFFEE" width="30%"><b>Description</b></td>
                      <td bgcolor="#FFFFEE" width="25%"><b>Weight</b></td>
                      <td bgcolor="#FFFFEE" width="7%"><b>Quantity</b></td>
                      <td bgcolor="#FFFFEE" width="8%"><b>Unit Price</b></td>
                    </thead>
                    <tr>
                      <td align="center" valign="top">
                            <input type="hidden" id="line" name="line" datafld="line" />
                            <input type="checkbox" id="selected" name="selected" datafld="selected" />
                      </td>
                      <td align="right" valign="top">
                        <div datafld="line"></div>
                      </td>
                      <td valign="top">
                        <div datafld="item"></div>
                      </td>
                      <td valign="top">
                        <div datafld="description"></div>
                      </td>
                      <td valign="top">
                        <div datafld="weight"></div>
                      </td>
                      <td align="center" valign="top">
                            <input type="text" id="quantity" name="quantity" datafld="quantity" style="text-align: right" size="5" maxlength="3" />
                      </td>
                      <td align="right" valign="top">
                        <div datafld="unitprice"></div>
                      </td>
                    </tr>
                  </table>
                 </td>
               </tr>
               <tr>
                 <td align="bottom">
                   <table width="100%" border="0">
                    <tr>
                      <td align="right">
                           Page <span id="currentpage"></span> of <span id="totalpages"></span>
                      </td>
                    </tr>
                  </table>
                 </td>
               </tr>
             </table>
            <p />
            <table width="100%" border="0">
              <tr>
                <td width="12%">
                  <input type="button" name="First" id="First" value="First" onclick="document.body.style.cursor = 'wait';objPage.showFirst();document.getElementById('currentpage').lastChild.nodeValue = objPage.page();document.body.style.cursor = 'auto'" />
                </td>
                <td width="12%">
                  <input type="button" name="Next" id="Next" value="Next" onclick="document.body.style.cursor = 'wait';objPage.showNext();document.getElementById('currentpage').lastChild.nodeValue = objPage.page();document.body.style.cursor = 'auto'" />
                </td>
                <td width="12%">
                  <input type="button" name="Previous" id="Previous" value="Previous" onclick="document.body.style.cursor = 'wait';objPage.showPrevious();document.getElementById('currentpage').lastChild.nodeValue = objPage.page();document.body.style.cursor = 'auto'" />
                </td>
                <td width="12%">
                  <input type="button" name="Last" id="Last" value="Last" onclick="document.body.style.cursor = 'wait';objPage.showLast();document.getElementById('currentpage').lastChild.nodeValue = objPage.page();document.body.style.cursor = 'auto'" />
                </td>
                <td width="12%"> </td>
                <td width="12%">
                  <input type="button" name="Update" id="Update" value="Update" onclick="document.body.style.cursor = 'wait';update();document.body.style.cursor = 'auto'" />
                </td>
                <td> </td>
              </tr>
            </table>
            <xml id="xmlWindow" async="false">
            </xml>
            <xml id="xmlFull" async="false"><%=Session("shoppingcart") %></xml>
          </body>
        </html>
        </td>
       </tr>
      </table>

      </body>

      </html>

          服務器端
          一旦客戶端的代碼編寫完成,就到了把注意力集中到購物車的服務器端上了。創建購物車的機制因電子商務系統的差異而有所不同,但是XLM數據島的基本布局就像下面列表D里面的一樣。

      <%@ Language=JScript %>

       <%

       /* ASP:               xmlServer

       Creation Date: May 12, 2003

       Programmer:    Edmond Woychowsky

       Purpose:       The purpose of this script is to handle client-side changes

       to the contents of an XML "shopping cart".


       Update Date:       Programmer:              Description:

       */

       var objXML = new ActiveXObject('MSXML2.FreeThreadedDOMDocument.4.0');

       objXML.loadXML(unescape(Request.ServerVariables.Item('HTTP_request')));


       if(objXML.parseError == 0) {                    //     Delete rows

       for(var i=0;i < objXML.getElementsByTagName('row').length;i++)

       if(eval(objXML.getElementsByTagName('selected').item(i).text)) {

       objXML.getElementsByTagName('root').item(0).removeChild(objXML.getElementsByTagName('row').item(i));


       --i;

       }


       //     Resequence lines

       for(var i=0;i < objXML.getElementsByTagName('line').length;i++)

       objXML.getElementsByTagName('line').item(i).text = (i + 1).toString();


       Session('shoppingcart') = objXML.xml;     //     Update session variable

       }


       Response.Write(Session('shoppingcart'));     //     Respond to client


       objXML = null;

       //     Clean up

       %>

          由于這只是一個演示版的應用程序,所以客戶端頁面代碼之后部分(見列表C)并沒有顯示出購物車最初是如何創建的,也沒有顯示任何數據庫邏輯。它把重點放在了購物車的操控上(見列表D)。當第一件物品被選中的時候,利用XML文檔對象模型(DOM),或者通過使用ADO的保存方法和XSLT就可以完成創建購物車了。以后的物品簡單地通過使用DOM或者XSLT就可以加在后面了。

          檢驗過程就是數據庫邏輯所在的地方。我使用DOM來瀏覽XML購物車,使用一個Oracle存儲過程來更新或者添加數據行,這真的對那些使用SQL服務器或者MySQL的購物車沒有什么幫助。

          第二次會更好
          使用XML數據島比較容易讓HTML具有清爽的外觀。這里沒有一行接一行的服務器端代碼,也沒有嵌入在循環里的單行HTML,這里有的是一行HTML。當有人在你剛剛完成購物車應用程序就建議添加一個數據列的時候,這個方法可以幫助你避免一些開發人員需要面對的維護惡夢。




      日韩精品一区二区三区高清