OK, I've tried a number of different ways to get around handling additional elements that aren't in the RSS 2.0 specification (such as trackback:ping, wfw:rssComments, slash:comments, etc. - basically anything using QName). First, I started with the way you are supposed to do it, referencing and importing namespaces, creating seperate xsd schemas and the using the ref attribute... that didn't work. So then I started hacking the document by adding the namespace to the elements of the XML on the fly, that didn't work either.
I've created a paired down version of my earlier schema (for testing purposes) that will grab the RSS 2.0 feed from the SPS Blog, but the hack is atrocious (look at the UndeclaredNamespace procedure). No matter what I try, I can't get MSXML4 and the XMLAdapter to behave and bring in those elements (with their content) without the hack. Anyone got any ideas, or better yet, solutions? I hope I'm missing something here and that it isn't a problem with MSXML4 with no workaround.
LOCAL loXMLAdapter, loBrowser, lcXSD, lcRSSContent, lcXMLHeader, lcXMLFooter
lcXMLHeader = GetHeader()lcXSD = VFPRSS2Schema()lcRSSContent = RetrieveRSS("http://www.sweetpotatosoftware.com/SPSBlog/SyndicationService.asmx/GetRss")UndeclaredNamespace(@lcRSSContent)lcXMLFooter = GetFooter()
oXMLAdapter = NEWOBJECT('XMLAdapter')
oXMLAdapter.LOADXML(lcXMLHeader + lcXSD+ lcRSSContent + lcXMLFooter)
CLOSE DATABASES ALLoXMLAdapter.TABLES(1).TOCURSOR && ItemoXMLAdapter.TABLES(2).TOCURSOR && ChanneloXMLAdapter.TABLES(3).TOCURSOR && RssSET
*****************************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
*****************************PROCEDURE UndeclaredNamespace(tcRSSContent)***************************** *!* Workaround for MSXML4 - This needs to be worked on still, I can't seem to get these elements even if *!* I split up the schemas and use imports and ref in element tag *!* However, this workaround at least ensures that it doesn't blow up with "Undeclared Namespace Prefix" error *!* while still retrieving the contents. I hate hacks like this, especially in this case because these elements aren't *!* part of the specification, but are on many blogs including mine. *!* Anyone got a better fix or know how to do this right? tcRSSContent = STRTRAN(tcRSSContent, "trackback:ping", [trackbackping], -1, -1, 1) tcRSSContent = STRTRAN(tcRSSContent, "pingback:server", [pingbackserver], -1, -1, 1) tcRSSContent = STRTRAN(tcRSSContent, "pingback:target", [pingbacktarget], -1, -1, 1) tcRSSContent = STRTRAN(tcRSSContent, "wfw:commentRSS", [wfwcommentRss], -1, -1, 1) tcRSSContent = STRTRAN(tcRSSContent, "wfw:comment", [wfwcomment], -1, -1, 1) tcRSSContent = STRTRAN(tcRSSContent, "slash:comment>", [slashcomments], -1, -1, 1)ENDPROC
*****************************FUNCTION VFPRSS2Schema()***************************** LOCAL lcXML TEXT TO lcXML NOSHOW<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" attributeFormDefault="qualified" elementFormDefault="qualified" > <xsd:element name="rss"> <xsd:complexType> <xsd:sequence> <xsd:element name="channel"> <xsd:complexType> <xsd:sequence> <xsd:element name="title" type="xsd:string" /> <xsd:element name="link" type="xsd:string" /> <xsd:element name="description" type="xsd:string" /> <xsd:element name="copyright" type="xsd:string" /> <xsd:element name="lastBuildDate" type="xsd:string" /> <xsd:element name="generator" type="xsd:string" /> <xsd:element name="managingEditor" type="xsd:string" /> <xsd:element name="webMaster" type="xsd:string" /> <xsd:element name="item"> <xsd:complexType> <xsd:sequence> <xsd:element name="trackbackping" type="xsd:string" maxOccurs="unbounded" /> <xsd:element name="pingserver" type="xsd:string" /> <xsd:element name="pingtarget" type="xsd:string" /> <xsd:element name="wfwcomment" type="xsd:string" /> <xsd:element name="wfwcommentRss" type="xsd:string" /> <xsd:element name="slashcomments" type="xsd:string" /> <xsd:element name="title" type="xsd:string" /> <xsd:element name="guid" type="xsd:string" /> <xsd:element name="link" type="xsd:string" /> <xsd:element name="pubDate" type="xsd:string" /> <xsd:element name="description" type="xsd:string" /> <xsd:element name="comments" type="xsd:string" /> <xsd:element name="category" type="xsd:string" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="version" type="xsd:decimal" use="required" /> </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("<rss", lcRetVal)) RETURN LEFT(lcRetVal, ATC("</rss>", lcRetVal) + 9) ENDIF ENDIF RETURN ""ENDFUNC
Remember Me
a@href@title, b, blockquote@cite, em, i, strike, strong, sub, super, u