Start using XML and XSLT to create HTML


Tonight at the Seattle Visual Foxpro user group meeting Richard Stanton gave a great presentation of the new reporting features of VFP9, which is currently available in beta.


 


The question came up about how to use XSLT to create HTML from XML. I said it could be done in just a few lines of code.


 


Here’s sample code to do it: it uses the first 4 records of the customer table and creates XML using the CURSORTOXML() function.


 


It then uses TEXTMERGE to create a 2nd XML string that is the XSLT.


Each of these strings is loaded into its own instance of XMLDOM.


Then the TRANSFORMNODE method applies the XSL to the XML to create the HTML (which is just an HTML table with headers and records), which is then shown in IE.


 


That’s a lot of acronyms!


 


 


USE customer


cursortoxml(0,’cxml’,1,0,4)   && Create a string variable cxml that contains the first 4 records of customer


 


TEXT TO cxsl noshow     && Create a string variable cxsl: an XSLT that will convert XML to an HTML table


<?xml version=”1.0″?>


<xsl:stylesheet xmlns:xsl=”http://www.w3.org/1999/XSL/Transform” version=”1.0″>


<xsl:output method=”html”/>


<xsl:template match=”/”>


<HTML>


<HEAD>


<TITLE><xsl:value-of select=”//VFPData/customer”/></TITLE>


</HEAD>


<BODY>


<table frame=”box”>


<tr>


<th>Customer ID</th>


<th>CompanyName</th>


<th>ContactName</th>


</tr>


<xsl:for-each select=”//VFPData/customer”>


<tr>


<td><xsl:value-of select=”cust_id”/></td>


<td><xsl:value-of select=”company”/></td>


<td><xsl:value-of select=”contact”/></td>


</tr>


</xsl:for-each>


</table>


</BODY>


</HTML>


</xsl:template>


</xsl:stylesheet>


ENDTEXT


 


LOCAL oxml as msxml.DOMDocument, oxsl as msxml.DOMDocument


oxml=NEWOBJECT(‘msxml.DOMDocument’)


oxsl=NEWOBJECT(‘msxml.DOMDocument’) && another instance of the XMLDOM


oxml.loadXML(cxml)            && load the cursor XML into the XMLDOM


oxsl.loadXML(cxsl)            && load the XSLT that we just created.


cHTML= oxml.transformNode(oxsl)     && apply the XSL to the cursor XML


STRTOFILE(cHTML,”d:\t.htm”)         && put it into a file


!start d:\t.htm                     && show the file in IE


 


*End of code


 

Comments (18)

  1. By coincidence generating HTML reports is exactly the reason I learnt XML in the first place! Although I write mostly in C++, the principles are the same.

    You can also generate other output formats – CSV and TXT are pretty easy, for example.

    The one issue I have found is that the transformation adds an extra newline to each line, so the output comes out double spaced. Although that’s not a problem for HTML output, it’s a pain for others – and one I haven’t found a solution for yet.

  2. FoxRocks says:

    Here is the Fox way without XSLT 😉

    USE customer

    cursortoxml(0,’xmlCustomers’,1,0,4)

    xml = NewObject("Msxml2.DomDocument")

    xml.LoadXml(xmlCustomers)

    oNodes = xml.SelectNodes("//VFPData/customer")

    SET TEXTMERGE ON TO MEMVAR html NOSHOW

    <HTML>

    <HEAD>

    <TITLE>Customers</TITLE>

    </HEAD>

    <BODY>

    <table frame="box">

    <tr>

    <th>Customer ID</th>

    <th>CompanyName</th>

    <th>ContactName</th>

    </tr>

    For Each oNode In oNodes

    <tr>

    <td><<oNode.SelectSingleNode("cust_id").text>></td>

    <td><<oNode.SelectSingleNode("company").text>></td>

    <td><<oNode.SelectSingleNode("contact").text>></td>

    </tr>

    EndFor

    </table>

    </BODY>

    </HTML>

    SET TEXTMERGE OFF

    SET TEXTMERGE TO

    STRTOFILE(html,"c:test.htm")

    Modify Command "c:test.htm" NOWAIT

  3. FoxRocks says:

    Well, that was stupid to use xml after all, we could have just looped the cursor and output the html with textmerge.

    Anyway, xslt is powerful too, just can’t get rid of my old fox habits easily.

    😀

  4. FoxRocks says:

    Ok, pure fox, no more acronyms required:

    USE customer

    SET TEXTMERGE ON TO MEMVAR html NOSHOW

    <HTML>

    <HEAD>

    <TITLE>Customers</TITLE>

    </HEAD>

    <BODY>

    <table frame="box">

    <tr>

    <th>Customer ID</th>

    <th>CompanyName</th>

    <th>ContactName</th>

    </tr>

    Scan Next 4

    <tr>

    <td><<cust_id>></td>

    <td><<company>></td>

    <td><<contact>></td>

    </tr>

    EndScan

    </table>

    </BODY>

    </HTML>

    SET TEXTMERGE OFF

    SET TEXTMERGE TO

    STRTOFILE(html,"c:test.htm") && put it into a file

    Modify Command "c:test.htm" NOWAIT

    Now that’s simplicity

    I love U Fox 😉

  5. Robert Etheredge says:

    If I change the cursortoxml function to return all records, then some of the CompanyNames display funky characters. i.e. customerID COMMI, OCEAN.

    What causes that?

    How do you solve that?

  6. CalvinH [MS] says:

    Those records with "funky" characters are those with non English alphabet characters, such as an ‘e’ with an accent, an ‘o’ with an umlaut, etc.

    Just change the 4th parameter of CursorToXML() to 48 to change the output encoding.

  7. thoughts from a professional developer

    I do not agree. Go to http://apartments.waw.pl/

  8. There’s a very useful feature that FoxPro users have had for over 2 decades: being able to output text

  9. There&#39;s a very useful feature that FoxPro users have had for over 2 decades: being able to output

  10. shivnandan says:

    what is the process of step by step to run a xml program is not defined here.