Ken Levy mentioned out on the UT yesterday that it would be a cool VFP open source project to create a table that RSS could be imported into and the exported out of. I thought it was an excellent idea. So, I played around with RSS 2.0 last night. After more than a little reading on the specifications for RSS 2.0, and some trial and error, I was able to create a workable XML schema (XSD) for RSS 2.0. When I say workable, I mean I wanted it to work with VFP's XMLAdapter class. I'll be working on the other RSS schemas as time permits.
Below is a runnable example using the new schema and pulling RSS 2.0 sample content from:http://media-cyber.law.harvard.edu/blogs/gems/tech/rss2sample.xml
It's a lot of code, but most of it is the XML schema, and that could be placed in a file to be used as the XMLAdapter's schema. I just wanted to provide an example here that runs right out of the box with a copy of VFP 9 and an internet connetction. Have fun! (I'll quit getting side-tracked and get back to Emal and VFP shortly)
LOCAL loXMLAdapter, loBrowser, lcXSD, lcRSSContent, lcXMLHeader, lcXMLFooter
lcXMLHeader = GetHeader()lcXSD = VFPRSS2Schema()lcRSSContent = RetrieveRSS("http://media-cyber.law.harvard.edu/blogs/gems/tech/rss2sample.xml")lcXMLFooter = GetFooter()
oXMLAdapter = NEWOBJECT('XMLAdapter')oXMLAdapter.LOADXML(lcXMLHeader + lcXSD + lcRSSContent + lcXMLFooter)
CLOSE DATABASES ALLoXMLAdapter.TABLES(1).TOCURSOR && CloudoXMLAdapter.TABLES(2).TOCURSOR && ImageoXMLAdapter.TABLES(3).TOCURSOR && TextinputoXMLAdapter.TABLES(4).TOCURSOR && EnclosureoXMLAdapter.TABLES(5).TOCURSOR && ItemoXMLAdapter.TABLES(6).TOCURSOR && ChannelSET
*****************************FUNCTION GetHeader()***************************** LOCAL lcHeader TEXT TO lcHeader NOSHOW<?xml version="1.0" encoding="utf-8" ?><VFPDataSet> ENDTEXT RETURN lcHeaderENDFUNC
*****************************FUNCTION GetFooter()***************************** LOCAL lcFooter TEXT TO lcFooter NOSHOW</VFPDataSet> ENDTEXT RETURN lcFooterENDFUNC
*****************************FUNCTION VFPRSS2Schema()***************************** LOCAL lcXML TEXT TO lcXML NOSHOW<xsd:schema id="VFPDataSet" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <xsd:element name="VFPDataSet" msdata:IsDataSet="true"> <xsd:complexType> <xsd:choice maxOccurs="unbounded"> <xsd:element name="channel"> <xsd:complexType> <xsd:sequence> <xsd:element name="title" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="link" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="description" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="language" minOccurs="0" maxOccurs="1" default="en-us"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="copyright" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="managingEditor" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="webMaster" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="pubDate" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="lastBuildDate" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="category" minOccurs="0" maxOccurs="unbounded"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="generator" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="docs" default="http://blogs.law.harvard.edu/tech/rss"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="cloud"> <xsd:complexType> <xsd:sequence> <xsd:element name="domain" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="port" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:integer"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="path" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="registerProcedure" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="protocol" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="ttl"> <xsd:simpleType> <xsd:restriction base="xsd:integer"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="image"> <xsd:complexType> <xsd:sequence> <xsd:element name="url" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="title" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="link" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="width" default="88"> <xsd:simpleType> <xsd:restriction base="xsd:decimal"> <xsd:maxInclusive value="144"></xsd:maxInclusive> <xsd:minInclusive value="0"></xsd:minInclusive> <xsd:fractionDigits value="0"></xsd:fractionDigits> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="height" default="31"> <xsd:simpleType> <xsd:restriction base="xsd:decimal"> <xsd:maxInclusive value="400"></xsd:maxInclusive> <xsd:minInclusive value="0"></xsd:minInclusive> <xsd:fractionDigits value="0"></xsd:fractionDigits> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="description"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="rating"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="textInput"> <xsd:complexType> <xsd:sequence> <xsd:element name="title"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="description"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="name"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="link"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="skipHours" minOccurs="0" maxOccurs="24"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="skipDays" minOccurs="0" maxOccurs="7"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="item"> <xsd:complexType> <xsd:sequence> <xsd:element name="title"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="link"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="description"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="author" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="category" minOccurs="0" maxOccurs="unbounded"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="comments" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="enclosure"> <xsd:complexType> <xsd:sequence> <xsd:element name="url" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:anyURI"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="length" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:integer"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="type" minOccurs="1" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="guid" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> <!-- <xsd:attribute name="isPermaLink" type="xs:boolean" default="true"></xsd:attribute> --> </xsd:simpleType> </xsd:element> <xsd:element name="pubDate" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> <xsd:element name="source" minOccurs="0" maxOccurs="1"> <xsd:simpleType> <xsd:restriction base="xsd:string"> </xsd:restriction> </xsd:simpleType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="version" default="2.0"></xsd:attribute> </xsd:complexType> </xsd:element> </xsd:choice> </xsd:complexType> </xsd:element></xsd:schema> ENDTEXT RETURN lcXMLENDFUNC
*****************************FUNCTION RetrieveRSS(tcURL)***************************** #DEFINE INTERNET_OPEN_TYPE_PRECONFIG 0 #DEFINE SYNCHRONOUS 0 #DEFINE INTERNET_FLAG_RELOAD 2147483648
DECLARE INTEGER InternetOpen IN WININET STRING Agent, ; INTEGER AccessType, STRING ProxyName, ; STRING ProxyBypass, INTEGER Flags
DECLARE INTEGER InternetOpenUrl IN WININET ; INTEGER hInternetSession, STRING Url, STRING Header, ; INTEGER HeaderLength, INTEGER Flags, INTEGER Context
DECLARE INTEGER InternetReadFile IN WININET INTEGER file, ; STRING @Buffer, INTEGER NumberOfBytesToRead, INTEGER @BytesRead
DECLARE SHORT InternetCloseHandle IN WININET INTEGER hInst
LOCAL lcAgent, lhInternetSession, lhFile, llOK, lnReturn, lcReadBuffer, lnBytesRead, lcRetVal
lcAgent = "VFP RSS 2.0 Reader" lhInternetSession = InternetOpen(lcAgent, INTERNET_OPEN_TYPE_PRECONFIG, "", "", SYNCHRONOUS)
IF lhInternetSession = 0 ? "Problem Encountered: Internet session cannot be established" ELSE lhFile = InternetOpenUrl( lhInternetSession, tcURL, '', 0, INTERNET_FLAG_RELOAD, 0) IF lhFile = 0 ? "Problem Encountered: URL cannot be opened" ELSE lcRetVal = "" llOK = .T. DO WHILE llOK lcReadBuffer = SPACE(1500) lnBytesRead = 0 lnReturn = InternetReadFile(lhFile, @lcReadBuffer, LEN(lcReadBuffer), @lnBytesRead) IF (lnBytesRead > 0) lcRetVal = lcRetVal + LEFT(lcReadBuffer, lnBytesRead) ENDIF llOK = (lnReturn = 1 AND lnBytesRead > 0) ENDDO InternetCloseHandle(lhFile) InternetCloseHandle(lhInternetSession) lcRetVal = SUBSTR(lcRetVal, ATC("<channel", lcRetVal)) RETURN LEFT(lcRetVal, ATC("</channel>", lcRetVal) + 9) ENDIF ENDIF RETURN ""ENDFUNC
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u