N341 Home Work 4 - Project

Modified

Thanks to Ken Bell and Ryan Hughes for suggesting to use variables to simplify embedding values from XML into HTML. Much simpler than my method. The source reference is: http://www.w3.org/TR/xslt20/#attribute-value-templates

Note

<FORM NAME=ONE>
    <INPUT type=text name="TWO" >
</form>

but has the following errors as XML/XSL:

  1. ONE must be quoted,
  2. text must be quoted,
  3. INPUT requires a matching end tag </INPUT>
  4. </form> must match <FORM>

Below is valid XML/XSL:

<FORM NAME="ONE">
    <INPUT type="text" name="TWO"/>
</FORM>

The solution is to require IE to check for new versions on every visit to a page. In IE: Tools | Internet Options | Temporary Internet Files | Settings | Every Visit to Page

The following error may occur when accessing XML files downloaded from one computer to another such as the ZIP files for the assignment. Vista (and perhaps XP) blocks access to files, presumably attempting to protect you from using files you have copied to your computer.

Unblock access to individual files by the following:

  1. Open in Windows Explorer the directory containing the file, either the XML file or one referenced by the XML.
  2. Right click on the file and open Properties.
  3. Click Unblock.

The XML page cannot be displayed

Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.


Access is denied. Error processing resource 'file:///W:/N341/Project/TraderSummaryContent.htm'.

 

Unblock access to all files in a directory by the following:

  1. Download Streams, copy Streams.exe to Windows directory if possible.
  2. To unblock all the files in directory c:\temp and any subdirectories enter:

    Streams –d –s c:\temp

 

Overview 

The stock trading site has two main functions: managing access to the site and managing site functions.

Managing access - Home work 3 completed the user interface for registration and logging in of stock traders and logging out the current trader out. The user view to manage access appears at right.

Managing function - This home work will complete the bulk of the user interface for the site function. The user view to manage site function appears at right. The new left menu provides access to the functions after user login, the center provides display of function results.

Our concern will be the user interface exclusively; managing the data and maintaining system integrity (i.e. programming logic) is the responsibility of software development. In the following, we will develop methods that allow testing each user interface module without the programming logic.

There are three main site functions.

  1. Account - Displays current account information such as name, address and balance.
  2. Portfolio - Displays the stocks owned, the value and total worth at current price.
  3. Shopping cart - The shopping cart metaphor describes much of the fundamental site operation.

User Interface - A common user interface structure with site navigation at top, application navigation at left and content in the center. Navigation will be completed in a later assignment.

For now, the major user interface content is implemented by the following style sheets:

  1. List current stock holdings and value (PortfolioContent.htm) - Mostly completed below.
  2. List the trader summary (TraderSummaryContent.htm) - Mostly completed below.
  3. List available stocks to buy (BuyListContent.htm). - Mostly completed below.
  4. List stocks owned to sell (SellListContent.htm).
  5. List shopping cart contents (CartSummaryContent.htm).

 

Review of PortfolioContent.htm

The portfolio is the list of an individual's stock SYMBOL, stock NAME, SHARES owned, PRICE, STOCK VALUE and TOTAL worth. The PortfolioContent.htm style sheet transforms the following XML data set to the HTML rendering below.

Portfolio.XML
<?xml-stylesheet type="text/xsl" href="PortfolioContent.htm"?>

<xml  xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
  <rs:data>
    <z:row SYMBOL="MSFT" NAME="Microsoft" SHARES="100" PRICE="10.0000" STOCKVALUE="1000.0000"/>
    <z:row SYMBOL="FORD" NAME="Ford Motor" SHARES="500" PRICE="15.6700" STOCKVALUE="7835.0000"/>
    <z:row SYMBOL="IBM" NAME="IBM" SHARES="10" PRICE="15.0500" STOCKVALUE="150.5000"/>
  </rs:data>
</xml>
PortfolioContent.htm
<xsl:stylesheet version="2.0" 
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns="http://www.w3.org/1999/xhtml" 
 xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
   <xsl:output method="html" />

   <xsl:template name="PortfolioContent">
               <h1>Portfolio Summary</h1>
               <xsl:for-each select="xml/rs:data/z:row">
                           <xsl:value-of select="@SYMBOL" />  - <xsl:value-of select="@SHARES" /> - 
                           <xsl:value-of select="@PRICE" /> - <xsl:value-of select="@STOCKVALUE" /> <br />
               </xsl:for-each>
   </xsl:template>

   <xsl:template match="/">
      <xsl:call-template name="PortfolioContent" />
   </xsl:template>
</xsl:stylesheet>

Portfolio Summary

MSFT - 100 - 10.0000 - 1000.0000
FORD - 500 - 15.6700 - 7835.0000
IBM - 10 - 15.0500 - 150.5000

The key points to review are:

  1. References the same node names in the XML from the Stock and Portfolio database tables and stock value field (i.e. SYMBOL, NAME, SHARES, PRICE, STOCKVALUE).
  2. Iteration over all children nodes of the XML tree using:

    This is how all XML trees are defined (i.e. node names) when generated using the Microsoft MSXML2.DOMDocument class from a database in ASP programs.

  • Starting
  1. Open FrontPage.
  2. Copy the two files above and save as:
    • W:\N341\Project\PortfolioContent.htm
    • W:\N341\Project\Portfolio.xml
  3. Test using the browser address line of:
    • W:\N341\Project\Portfolio.xml

 

PortfolioContent.htm - Improvement 1

The key improvement we will make is:

  1. Output in a table organization.
  2. Formatting of numeric and currency values using:
  3. Summation over all STOCKVALUE children nodes in the XML tree by:
PortfolioContent.htm
<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
                       xmlns="http://www.w3.org/1999/xhtml" 
                       xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
  <xsl:output method="html" />

  <xsl:template name="PortfolioContent">
    <h1>Portfolio</h1>
    <table border="1">
        <tr>
          <td>Symbol</td>
          <td>Shares</td>
          <td>Price</td>
          <td>Value</td>
        </tr>
        <xsl:for-each select="xml/rs:data/z:row">
          <tr>
            <td><xsl:value-of select="@SYMBOL" /></td>
            <td><xsl:value-of select="@SHARES" /></td>
            <td><xsl:value-of select="format-number(@PRICE, '$#,###,###.00')" /></td>
            <td><xsl:value-of select="format-number(@STOCKVALUE, '$#,###,###.00')" /></td>
           </tr>
       </xsl:for-each>
       <tr>
         <td></td>
         <td></td>
         <td>Total</td>
         <td>
           <xsl:value-of select="format-number(sum(xml/rs:data/z:row/@STOCKVALUE), '$#,###,###.00')" />
         </td>
      </tr>
    </table>
 </xsl:template>

<xsl:template match="/">
     <xsl:call-template name="PortfolioContent" />
</xsl:template>		
</xsl:stylesheet>

Portfolio

Symbol Shares Price Value
MSFT 100 $10.11 $1,011.00
GMC 20 $38.10 $762.00
FORD 15 $15.67 $235.05
FORD 100 $15.67 $1,567.00
UAL 230 $7.64 $1,757.20
IBM 10 $15.05 $150.50
Total $5,482.75

 

  • PortfolioContent.htm
  1. Copy the above PortfolioContent.htm and save.
  2. Modify PortfolioContent.htm to output NAME of stock also.
  3. Save and test using the browser address line of:
    • W:\N341\Project\Portfolio.xml
  4. Your results should appear similar to above but with the NAME field displayed.

 

TraderSummaryContent.htm

The trader summary is the account information of trader's ID, FIRSTNAME, LASTNAME, and BALANCE.

The XML below for testing has been copied to the Project directory. TraderSummaryContent.htm remains for you to create.

TraderSummary.XML
<?xml-stylesheet type="text/xsl" href="TraderSummaryContent.htm"?>

<xml xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
	<rs:data>
		<z:row ID="Ray" FIRSTNAME="Raymond" LASTNAME="Wisman" BALANCE="990.0000"/>
	</rs:data>
</xml>

 

  • TraderSummaryContent.htm
  1. In FrontPage, open PortfolioContent.htm.
  2. Save as TraderSummaryContent.htm
  3. Test using the browser address line of:
    • W:\N341\Project\TraderSummary.xml
  4. You may get a browser error.
  • Edit
  1. Modify TraderSummaryContent.htm to output trader's ID, FIRSTNAME, LASTNAME, and BALANCE.
    • Format BALANCE as currency.
    • Add appropriate headings.
  2. Save and test using the browser address line of:
    • W:\N341\Project\TraderSummary.xml
  3. Results should appear as the below.

Trader Summary

ID First Last Balance
Ray Raymond Wisman $990.00

 

BuyListContent.htm

  1. Lists stocks available to buy. Displays SYMBOL, NAME and PRICE.
  2. Provides a text box for entry of number of stocks to buy.
  3. Submits SYMBOL and number of each stock using a form defined as:

    <form name="StockListForm" method="get" action="BuyStock.asp">

The XML below for testing has been copied to the Project directory.

BuyList.XML
<?xml-stylesheet type="text/xsl" href="BuyListContent.htm"?>

<xml xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
	<rs:data>
		<z:row SYMBOL="MSFT" NAME="Microsoft" PRICE="10.0000"/>
		<z:row SYMBOL="GMC" NAME="General Motors" PRICE="38.1000"/>
		<z:row SYMBOL="FORD" NAME="Ford Motor" PRICE="15.6700"/>
		<z:row SYMBOL="UAL" NAME="United Airlines" PRICE="7.6400"/>
		<z:row SYMBOL="IBM" NAME="IBM" PRICE="15.0500"/>
	</rs:data>
</xml>

 

  • BuyListContent.htm
  1. In Frontpage, open PortfolioContent.htm.
  2. Save as BuyListContent.htm
  3. Test using the browser address line of:
    • W:\N341\Project\BuyList.xml
  4. You may get an error.
  • First cut
  1. Modify BuyListContent.htm to output stock SYMBOL, NAME and PRICE, format PRICE as dollars and cents.
  2. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml
  • Second cut - The table generated needs to be inside a form.
  1. Define the form immediately above the <table.. by:
    • <form name="StockListForm" method="get" action="BuyStock.asp">
  2. Immediately after </table> terminate the form by:
    • </form>
  3. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml
  • Third cut - The form needs text boxes for the number of each stock and a single Submit button.
  1. Add a column to the table titled Number.
  2. Add text input in the Number column after the @PRICE is displayed:
    • <input type="text" value="0" name="IBM" />
  3. Add a single Submit button to the form.
    • Hint:    Don't name the SUBMIT button. Defining a name attribute on the SUBMIT button will send the button on the URL along with the other input attributes.
  4. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml
    • Enter some numbers in the text box.
    • Submit.
  5. You may have received an error but, more importantly, the address line holds what was sent to the BuyStock.ASP script. Note that IBM is repeated, we need the actual stock SYMBOL instead.
  • Fourth cut - The input needs the @SYMBOL instead of name="IBM" for each stock.
  1. Change "IBM" to "@SYMBOL"
    • <input type="text" value="0" name="@SYMBOL" />
  2. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml
    • Enter some numbers.
    • Submit.
  3. That's worse!
  • Fifth cut - Problem is we need the @SYMBOL value by:
    • <xsl:value-of select="@SYMBOL" />
  1. Change @SYMBOL to <xsl:value-of select="@SYMBOL" />
    • <input type="text" name="<xsl:value-of select="@SYMBOL"/> "/>
  2. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml
  3. That's even worse! Now we have a syntax error!
  • Sixth cut - Problem is the '<' of '<xsl':
    • <input type="text" name="<xsl:value-of select="@SYMBOL"/> "/>
    which means the start of some tag. Since <input started a tag the <xsl confuses the parser.
    While we cannot follow one < by another <, we can use XSL variables to accomplish the desired results:

    <xsl:variable name="x" select="@SYMBOL"/>

    assigns variable x the value of @SYMBOL. Then use the variable x within the HTML.

    <input Type="TEXT" Name='{$x}' value="0" size="4"/>
     

  1. Change: <input type="text" name="<xsl:value-of select="@SYMBOL"/> "/>
    <xsl:variable name="x" select="@SYMBOL"/>
    <input Type="TEXT" Name='{$x}' value="0" size="4"/>
    

  2. Save and test using the browser address line of:
    • W:\N341\Project\BuyList.xml 
    • Enter some numbers.
    • Submit.
  3. The browser address line should hold the SYMBOL and number of stock to buy similar to:
    • BuyStock.asp?MSFT=4&GMC=0&FORD=5&UAL=0&IBM=0

Sample HTML generated

<h1>Buy Stock</h1>
<form name="StockListForm" method="get" action="BuyStock.asp">
  <table border="1">
   <tr>
     <td>Symbol</td> <td>Name</td>     <td>Price</td>    <td>Number</td>
   </tr>
   <tr>
     <td>MSFT</td>  <td>Microsoft</td>  <td>$10.00</td>  <td>  <input Type="TEXT" Name="MSFT" value="0" size="4"/> </td>
   </tr>
   <tr>
     <td>GMC</td><td>General Motors</td><td>$38.10</td><td> <input Type="TEXT" Name="GMC" value="0" size="4"/> </td>
   </tr>
  </table>
  <input type="submit"/>
</form>

 

Debugging

Often we need to see the HTML produced by the style sheet for debugging. The browser source view only displays the XML file, not useful when debugging style sheets.

  1. Open a COMMAND prompt window.
     
  2. Generate HTML by:
    • msxsl BuyList.xml BuyListContent.htm
       
  3. To write the HTML to file test.htm:
    • msxsl BuyList.xml BuyListContent.htm > test.htm
       
  4. The test.htm HTML can be opened in Frontpage to see what the transformation produces or can be opened by a browser.

 

 

SellListContent.htm

  1. Lists all stocks owned by a trader.
  2. Displays SYMBOL, NAME, PRICE, SHARES, STOCKVALUE.
  3. Provides a text box for entry of number of stocks to buy.
  4. Submits SYMBOL and number of each stock using a form defined as:

    <form name="StockSellForm" method="get" action="SellStock.asp">

The below XML for testing has been copied to the Project directory.

SellList.XML
<?xml-stylesheet type="text/xsl" href="SellListContent.htm"?>

<xml  xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
 <rs:data>
	<z:row SYMBOL="MSFT" NAME="Microsoft" SHARES="100" PRICE="10.0000" STOCKVALUE="1000.0000"/>
	<z:row SYMBOL="FORD" NAME="Ford Motor" SHARES="500" PRICE="15.6700" STOCKVALUE="7835.0000"/>
	<z:row SYMBOL="IBM" NAME="IBM" SHARES="10" PRICE="15.0500" STOCKVALUE="150.5000"/>
 </rs:data>
</xml>

 

  • SellListContent.htm

The solution is nearly the same as BuyListContent.htm.

  1. In FrontPage, open BuyListContent.htm.
  2. Save as SellListContent.htm
  • First cut
  1. Modify SellListContent.htm to output SYMBOL, NAME, PRICE, SHARES, STOCKVALUE.
  2. Save and test using the browser address line of:
    • W:\N341\Project\SellList.xml
  • Second cut - Need column for Sell titled and text input.
  1. Add as the last column titled Sell to the table.
  2. Add text input in the last column by:
    • <input type="text" ...
    • Follow the same approach used in BuyListContent.htm for input.
  3. Change the <form action="BuyStock.asp"... to SellStock.asp.
  4. Test:
    • Enter a number of stocks to sell.
    • Submit.

      Because there is no SellStock.asp the browser may report an error containing the browse address line.

      The address line should be similar to:

      SellStock.asp?MSFT=5&FORD=10&IBM=0

 

 

CartSummaryContent.htm

  1. Lists all stocks in the shopping cart.
  2. Displays TRADEID, SYMBOL, SHARES, PRICE, BUY.
  3. Provides a check box for whether to remove trade from cart.
  4. Submits boxes checked using a form defined as:
    <form name="CartListForm" method="get" action="CartEdit.asp">

The below XML for testing has been copied to the Project directory.

CartSummary.XML
<?xml-stylesheet type="text/xsl" href="CartSummaryContent.htm"?>

<xml xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
	<rs:data>
		<z:row TRADEID="95" ID="Ray" SYMBOL="IBM" PRICE="20.0000" SHARES="5" BUY="False"/>
		<z:row TRADEID="100" ID="Ray" SYMBOL="MSFT" PRICE="10.0000" SHARES="10" BUY="True"/>
		<z:row TRADEID="101" ID="Ray" SYMBOL="MSFT" PRICE="10.0000" SHARES="100" BUY="False"/>
	</rs:data>
</xml>

 

  • CartSummaryContent.htm

The solution is similar to BuyListContent.htm and SellListContent.htm.

  1. In FrontPage, open BuyListContent.htm.
  2. Save as CartSummaryContent.htm
  • First cut
  1. Modify CartSummaryContent.htm to output TRADEID, SYMBOL, SHARES, PRICE, BUY.
  2. Save and test using the browser address line of:
    • W:\N341\Project\CartSummary.xml
  • Second cut - Need column for Remove titled and checkbox.
  1. Add as the last column titled Remove to the table.
  2. Add checkbox in the last column by:
    • <input type="checkbox" name="@TRADEID"/>
  3. Create the <form action="CartEdit.asp" file similar to the BuyStock.asp. The CartEdit.asp file must have at least one line.
  4. Save and test using the browser address line of:
    • W:\N341\Project\CartSummary.xml
    • Check 2 boxes.
    • Submit.
    • Because there is no CartEdit.asp the browser may report an error containing the browse address line.

       

  5. Address line looks similar to:
    • CartEdit.asp?@TRADEID=on&@TRADEID=on

    but we need each TRADEID identified. The address line should be:

    • CartEdit.asp?95=on&101=on
  • Third cut - Problem is same we had for the @SYMBOL in BuyListContent.htm but here we have:
    • <input type="checkbox" name="@TRADEID"/>

    Follow the same approach for @TRADEID.

     

  • Fourth cut - The BUY field of the Cart table has a True or False value. Rather than displaying True or False in the Buy/Sell column, display Buy when @BUY is True and Sell when @BUY is False. The <xsl:if was discussed earlier in class, click for the notes.
    • For example, use:
      •  <xsl:if test="@BUY = 'True'">

Sample HTML generated

<h1>Stock Cart Contents</h1>
<form name="CartEditForm" method="get" action="CartEdit.asp">
 <table border="1">
  <tr>
   <td>Trade</td><td>Symbol</td><td>Number</td><td>Price</td><td>Buy/Sell</td><td>Remove</td>
  </tr>
  <tr>
   <td>95</td><td>IBM</td><td>5</td><td>$20.00</td><td>Sell</td><td><input Type="checkbox" Name="95"/></td>
  </tr>
  <tr>
   <td>100</td><td>MSFT</td><td>10</td><td>$10.00</td><td>Buy</td><td><input Type="checkbox" Name="100"/></td>
  </tr>
 </table>
 <input type="submit"/>
</form>

 

PortfolioContent.htm - Improvement 2

The improvement below adds JavaScript to generate a line chart showing price of each stock in the portfolio.

PortfolioContent.htm
<xsl:stylesheet version="2.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
                       xmlns="http://www.w3.org/1999/xhtml" 
                       xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
  <xsl:output method="html" />

  <xsl:template name="PortfolioContent">
    <h1>Portfolio</h1>
    <table border="1">
        <tr>
          <td>Symbol</td>
          <td>Shares</td>
          <td>Price</td>
          <td>Value</td>
        </tr>
        <xsl:for-each select="xml/rs:data/z:row">
          <tr>
            <td><xsl:value-of select="@SYMBOL" /></td>
            <td><xsl:value-of select="@SHARES" /></td>
            <td><xsl:value-of select="format-number(@PRICE, '$#,###,###.00')" /></td>
            <td><xsl:value-of select="format-number(@STOCKVALUE, '$#,###,###.00')" /></td>
           </tr>
       </xsl:for-each>
       <tr>
         <td></td>
         <td></td>
         <td>Total</td>
         <td>
           <xsl:value-of select="format-number(sum(xml/rs:data/z:row/@STOCKVALUE), '$#,###,###.00')" />
         </td>
      </tr>
    </table>
    <span id="displayChart">.</span>

    <script language="JavaScript">
         var req = new ActiveXObject("Microsoft.XMLHTTP"); // For IE only;

         req.open("GET", "Portfolio.xml", false);
         req.send(null);

         var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
         xmlDoc.async = false;
         xmlDoc.loadXML(req.responseText);

         var elementArray = xmlDoc.getElementsByTagName('xml/rs:data/z:row');

         labels = new Array();
         var max = 0;

         for(i=0; i != elementArray.length; i++)
                  labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]=0;

         for(i=0; i != elementArray.length; i++) {
                  labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]=
                           labels[elementArray[i].attributes.getNamedItem("SYMBOL").value] +
                           parseFloat(elementArray[i].attributes.getNamedItem("PRICE").value);
                  max = Math.max(max,labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]);
         }

         chartData="";
         chartLabels="";

         for( var i in labels ) {
                  chartLabels = chartLabels + i + " $" + labels[i]+"|";
                  chartData = chartData + labels[i]+",";
         }

         chartData=chartData.substring(0,chartData.length-1);
         chartLabels=chartLabels.substring(0,chartLabels.length-1);

         displayChart.innerHTML =
        '<img src="http://chart.apis.google.com/chart?cht=lc&amp;chs=375x150&amp;chl=' + chartLabels +  '&amp;chd=t:' + chartData + '&amp;chds=0,' + max + '"/>';

        document.write('http://chart.apis.google.com/chart?cht=lc&amp;chs=375x150&amp;chl=' + chartLabels +  '&amp;chd=t:' + chartData + '&amp;chds=0,' + max);
   </script>
 

 </xsl:template>

<xsl:template match="/">
     <xsl:call-template name="PortfolioContent" />
</xsl:template>		
</xsl:stylesheet>
Portfolio.xml

<?xml-stylesheet type="text/xsl" href="PortfolioContent.htm"?>

<xml  xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
  <rs:data>
    <z:row SYMBOL="MSFT" NAME="Microsoft" SHARES="100" PRICE="10.0000" STOCKVALUE="1000.0000"/>
    <z:row SYMBOL="FORD" NAME="Ford Motor" SHARES="500" PRICE="15.6700" STOCKVALUE="7835.0000"/>
    <z:row SYMBOL="IBM" NAME="IBM" SHARES="10" PRICE="15.0500" STOCKVALUE="150.5000"/>
  </rs:data>
</xml>

 

  1. Modify your PortfolioContent.htm to add the chart above line chart by copying and pasting the grayed JavaScript.
  2. Save and test using the browser address line of:
    • W:\N341\Project\Portfolio.xml
  3. Your results should appear similar to above.
  4. The JavaScript currently sums the PRICE of each stock. Modify to sum the STOCKVALUE of each stock instead. Verify that the labels are accurate.
  5. Modify the JavaScript to display the total value (STOCKVALUE) of each stock in a pie chart.

    Results should be similar to:

Hints

  1. The JavaScript needs only minor changes to use STOCKVALUE in place of PRICE.
  2. To create a pie chart instead of a line chart, look over HW3 and the parameter names used. The chart above is generated by:

    http://chart.apis.google.com/chart?cht=p3&chs=375x150&chl=MSFT $1000|FORD $7835|IBM $150.5&chd=t:1000,7835,150.5&chds=0,7835
     

  3. Remember that, for debugging, JavaScript can display variable values using document.write(). The line graph URL is displayed by:

            document.write('http://chart.apis.google.com/chart?cht=lc&amp;chs=375x150&amp;chl=' + chartLabels +  '&amp;chd=t:' + chartData + '&amp;chds=0,' + max);
     

    or:

    http://chart.apis.google.com/chart?cht=lc&chs=375x150&chl=MSFT $1000|FORD $7835|IBM $150.5&chd=t:1000,7835,150.5&chds=0,7835

 

Explanation of JavaScript
In Homework 3 we saw how to access a XML file and how to produce a hard-coded Google chart, 
here we combine these ideas to produce the chart dynamically from the XML data. 
 
Associative arrays
In JavaScript, simply using an array creates the entry.
x[3] = "IBM";
One new concept used here is associative arrays. Arrays are indexed, commonly by an integer:
x[3] = "IBM";
y[ i ] = 130.75;
JavaScript also supports associative arrays which can be indexed by a string:
s["PRICE"] = 130.75;
z["SYMBOL"] = "IBM";
One difference of associative arrays is iterating, since the index can be any string, the index is not predefined. 
A for-statement that returns the index can be used, for example:
labels["MSFT"] = 10;
labels["FORD"] = 20;
labels["IBM"] = 30;
for(var i in labels)
	document.write( i + " is " + labels[ i ] + "<br/>");
writes:
MSFT is 10
FORD is 20
IBM is 30
The key JavaScript concepts are:
elementArray =
 xmlDoc.getElementsByTagName('xml/rs:data/z:row');
Create array with the elements for each row of the XML.
You can think of elementArray[0] with the values from the first row of the XML:
SYMBOL="MSFT"
NAME
="Microsoft"
SHARES
="100"
PRICE
="10.0000"
STOCKVALUE
="1000.0000"
labels = new Array(); Create an array named labels.
elementArray[ 0 ].attributes.getNamedItem("SYMBOL").value From the first XML row, i=0, the value is "MSFT".
for(i=0; i != elementArray.length; i++)
 labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]=0;
 
Purpose is to create and initialize labels array entries to 0.

Iterate over all the 0, 1, 2 rows, elementArray.length is 3 for the XML below.

When i=0, we set: labels["MSFT"]=0
When i=1, we set: labels["FORD"]=0
When i=2, we set: labels["IBM"]=0

elementArray[i].attributes.getNamedItem("PRICE").value From the first XML row, i=0, the PRICE value is "10.0000".

Convert to a float value.

for(i=0; i != elementArray.length; i++)
  labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]=
  labels[elementArray[i].attributes.getNamedItem("SYMBOL").value] +
  parseFloat(elementArray[i].attributes.getNamedItem("PRICE").value);
Sum the PRICE for each SYMBOL.

labels["MSFT"] = labels["MSFT"] + 10.0

max = Math.max(
  max,labels[elementArray[i].attributes.getNamedItem("SYMBOL").value]);
Google charts does not automatically scale data.
Scale from 0 to maximum.
for( var i in labels ) {
   chartLabels = chartLabels + i + " $" + labels[i]+"|";
   chartData = chartData + labels[i]+",";
}
The index, i, is MSFT, etc. then label[i] is 1000.00, etc.

Create chart labels by concatenating: "MSFT" + "$" + "10.0000" + "|", or "MSFT $10.0000|"

MSFT $10.00|FORD $15.67|IBM $15.05|

Create chart data by concatenating: "10.00" + ",", or "10.00,"

10,15.67,15.05,

chartData=chartData.substring(0,chartData.length-1);
chartLabels=chartLabels.substring(0,chartLabels.length-1);
Remove the extra "|" and ",".
Final result, note that the &amp; of the JavaScript are converted to &. <img src="http://chart.apis.google.com/chart?cht=lc&chs=375x150&
chl=MSFT $10.00|FORD $15.67|IBM $15.05&chd=t:10,15.67,15.05&chds=0,15.67 "/>

 

Portfolio.XML
<?xml-stylesheet type="text/xsl" href="PortfolioContent.htm"?>

<xml  xmlns:rs="urn:schemas-microsoft-com:rowset"  xmlns:z="#RowsetSchema">
  <rs:data>
    <z:row SYMBOL="MSFT" NAME="Microsoft" SHARES="100" PRICE="10.0000" STOCKVALUE="1000.0000"/>
    <z:row SYMBOL="FORD" NAME="Ford Motor" SHARES="500" PRICE="15.6700" STOCKVALUE="7835.0000"/>
    <z:row SYMBOL="IBM" NAME="IBM" SHARES="10" PRICE="15.0500" STOCKVALUE="150.5000"/>
  </rs:data>
</xml>
 
Enhancement understanding
For testing purposes, we GET a XML file:
req.open("GET", "Portfolio.xml", false); 
In practice, even though the same file name (Portfolio.xml) is used for XSL and JavaScript, a Web server would over-write the same file with data for different users. 
The correct solution is for the server to execute a program to produce the XML for the current user. 
The change is minor to execute PortfolioXML.asp and generate the most up-to-date XML:
req.open("GET", "PortfolioXML.asp", false); 
Of course, someone would need to implement the on PortfolioXML.asp the server, perhaps the N342 class? The ASP script using the project database would be:
PortfolioXML.asp
<%@ Language=JScript%>
<%
   conn = Server.CreateObject("ADODB.Connection");
   conn.Mode = 3;
   conn.Open ("DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" +
                      Server.MapPath("Project.mdb"));
   rs = conn.Execute("SELECT * FROM PORTFOLIO");

   var xmlDoc = Server.CreateObject("Msxml2.DOMDocument");
   xmlDoc.async = false;
   rs.Save (xmlDoc, 1) ;                  // Convert rs recordset to xmlDoc as XML tree
   xmlDoc.Save (Response, 1);        // Output XML as Response
   conn.Close();
%>

 

Assignment

  1. Modify listing of current stock holdings to include stock name (PortfolioContent.htm) and a pie chart of stock values.
  2. List the trader summary (TraderSummaryContent.htm).
  3. List available stocks to buy (BuyListContent.htm).
  4. List stocks owned to sell (SellListContent.htm).
  5. List shopping cart contents (CartSummaryContent.htm).

Turn in - Due before class on the date listed in the syllabus.

  1. OnCourse Drop Box
    1. Compress the Project folder containing the homework files.
      • In Windows Explorer, right-click on the Project folder.
      • Click Send to then click Compressed (zipped) Folder.
      • Project.zip will be created.
    2. Upload Project.zip to your CSCI N341 OnCourse Drop Box using the Display Name of HW4.
       
  2. Web server
    1. Copy files to W:\N341\Project drive
    2. Test in IE. The Welcome.xml is a default page.
      • In browser address enter: http://iu-uits-eiwp1.ads.iu.edu/username/N341/Project/Welcome.xml
         
  3. Email notice of completion to rwisman@ius.edu with subject: YOUR NAME - N341 HW4 - username