Generating VBScript to read a blog
Sometimes I need to test something using VBScript. A user sends a code snippet and asks why it behaves a certain way. Examining the behavior in VB can help.
Below is a VFP code sample which demonstrates VBScript code which uses several objects to read the RSS feed from my blog, do an XSLT transform on it so it displays nicely, and shows it in IE. (See Use a simple XSLT to read the RSS feed from a blog. )
First an XSLT file is created using Text…EndText. This is like a template to transform the XML to HTML. (Since it’s in XML format, literal characters such as “<” or “>” (which are used quite often in HTML!) are substituted with “<” and “>”)
Then it creates a script file called c:\t.vbs which contains the VB Script. The WinHTTPRequest object is used to get the XML RSS feed. The MSXML TransformNode method is used to do the transform. The Scripting.FileSystemObject is used to do File I/O.
Then VFP invokes Windows Scripting Host to run the script using wscript.exe
To convert the “&” back to “&”, a VFP COM object is used. Is there an easy way in VB Script to do the VFP STRTRAN function?
Some VB Script gotchas:
- IF requires a THEN on the same line
- ENDIF needs a space “END IF”
- If a call returns a value that is an object, the SET command is required
- Method calls don’t require parentheses for parameters unless the return value is assigned to a value.
- VFP allows 3 types of string delimiters (single, double quote, and square brackets), allowing easy embedding of quotes. VB only has the single quote.
- Doing a STRTRAN isn’t trivial in VB
- STRTOFILE and FILETOSTR are trivial in VFP
- Generating a text file using TEXTMERGE is simple in VFP
cXSLTFile="c:\t.xslt"
cHTMFile="c:\t.htm"
cScriptFile="c:\t.vbs"
cUrl="https://blogs.msdn.com/calvin_hsia/Rss.aspx"
TEXT TO cXSLT noshow
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="https://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<HTML><body>
<title><xsl:value-of select="//rss/channel/title"/></title>
<xsl:for-each select="//rss/channel/item">
<font color="#ff00ff" size="5">
<a href="<xsl:value-of select="link"/>"><xsl:value-of select="title"/></a>
</font>
<p><xsl:value-of select="pubDate"/></p>
<p><xsl:value-of select="description"/></p>
<br/>
</xsl:for-each>
</body></HTML>
</xsl:template>
</xsl:stylesheet>
ENDTEXT
STRTOFILE(cXSLT,cXSLTFile) && write out the XSLT
IF .f. && the VFP way. Try this if you’re having problems
oHTTP=CREATEOBJECT("winhttp.winhttprequest.5")
oHTTP.Open("GET",cUrl,.f.)
oHTTP.Send()
oXML=CREATEOBJECT("msxml.domdocument")
oXML.loadXML(oHTTP.ResponseText)
oXSLT=CREATEOBJECT("msxml.domdocument")
oXSLT.load(cXSLTFile)
cTrans=oxml.transformNode(oxslt) && do the XSLT transform
cTrans=STRTRAN(cTrans,"&","&") && convert "&" to "&"
cTrans=STRTRAN(cTrans,">",">")
cTrans=STRTRAN(cTrans,"<","<")
STRTOFILE(cTrans,cHTMFile)
oie=CREATEOBJECT("internetexplorer.application")
oie.visible=1
oie.navigate(cHTMFILE)
RETURN
ENDIF
TEXT TO myvar TEXTMERGE
SET oHTTP = CREATEOBJECT("winhttp.winhttprequest.5.1")
oHTTP.Open "GET","<<cURL>>", 0
oHTTP.Send
SET oXML=CREATEOBJECT("msxml.domdocument")
oXML.loadXML(oHTTP.ResponseText)
SET oXSLT=CREATEOBJECT("msxml.domdocument")
oXSLT.load("<<cXSLTFile>>")
cTrans=oXML.TransformNode(oXSLT)
SET fs=CREATEOBJECT("scripting.filesystemobject")
IF fs.FileExists("<<cHTMFile>>") then
fs.DeleteFile("<<cHTMFile>>")
END if
SET h=fs.CreateTextFile("<<cHTMFile>>",0,1)
SET oVFP=CREATEOBJECT("t1.c1") ' use VFP to convert "&" to "&"
cTrans = oVFP.MyEval("strtran(p2,p3,p4)",cTrans,"&","&")
cTrans = oVFP.MyEval("strtran(p2,p3,p4)",cTrans,">",">")
cTrans = oVFP.MyEval("strtran(p2,p3,p4)",cTrans,"<","<")
h.Write(cTrans)
h.Close
SET oIE=CREATEOBJECT("internetexplorer.application")
oIE.Visible=1
oIE.Navigate("<<cHTMFile>>")
ENDTEXT
STRTOFILE(myvar,cScriptFile)
PUBLIC x as wscript.shell
x=CREATEOBJECT("wscript.shell") && WSH
x.Exec("wscript "+cScriptFile)
84122