Monday, November 08, 2010 at 12:07 AM.

system.verbs.builtins.xml.rss.getOpmlFeeds

on getOpmlFeeds (opmltext, adrfeeds, adrlistinfo=nil) {
	<<Changes
		<<9/17/09; 6:59:08 AM by DW
			<<If there's a <link> in the <head> with rel == "alternate" use it to set the link in the listinfo table. 
		<<9/3/09; 3:54:29 AM by DW
			<<Add optional adrlistinfo param, if non-nil, we copy info about the OPML into the table.
		<<7/28/09; 3:42:49 PM by DW
			<<Created. Get a list of feeds from OPML. Dives into any level of hierarchy and pulls out the feeds.
	local (xstruct, now = clock.now ());
	on decode (s) {
		return (xml.entitydecode (s, flAlphaEntities:true))};
	xml.compile (opmltext, @xstruct);
	<<scratchpad.getopmlxstruct = xstruct
	new (tabletype, adrfeeds);
	local (adropml = xml.getaddress (@xstruct, "opml"));
	bundle { //listinfo, 9/3/09 by DW
		if adrlistinfo != nil {
			new (tabletype, adrlistinfo);
			adrlistinfo^.title = "";
			adrlistinfo^.dateCreated = now;
			adrlistinfo^.dateModified = now;
			try {
				local (adrhead = xml.getaddress (adropml, "head"));
				try {adrlistinfo^.title = decode (xml.getvalue (adrhead, "title"))};
				try {adrlistinfo^.dateCreated = date (xml.getvalue (adrhead, "dateCreated"))};
				try {adrlistinfo^.dateModified = date (xml.getvalue (adrhead, "dateModified"))};
				bundle { //find the link, 9/17/09 by DW
					local (adr);
					for adr in adrhead {
						if nameof (adr^) endswith "link" {
							local (adratts = @adr^.["/atts"]);
							if string.lower (adratts^.rel) == "alternate" {
								if adratts^.type == "text/html" {
									if sizeof (adratts^.href) > 0 {
										adrlistinfo^.link = adratts^.href};
									break}}}};
					if not defined (adrlistinfo^.link) {
						adrlistinfo^.link = ""}}}}};
	local (adrbody = xml.getaddress (adropml, "body"));
	on processOutline (adroutline, flfirstlevel) {
		local (adrsuboutline);
		if not flfirstlevel {
			local (adratts = @adroutline^.["/atts"]);
			if defined (adratts^) {
				if defined (adratts^.type) {
					if adratts^.type == "rss" {
						local (adrsubtable = @adrfeeds^.[adratts^.xmlUrl]);
						new (tabletype, adrsubtable);
						adrsubtable^.atts = adratts^}}}};
		for adrsuboutline in adroutline {
			if nameof (adrsuboutline^) endswith "outline" {
				processOutline (adrsuboutline, false)}}};
	processOutline (adrbody, true)}
<<bundle //test code
	<<local (f = frontier.pathstring + "twOpml:nytnewbie.opml")
	<<local (s = string (file.readwholefile (f)))
	<<local (s = file.readwholefile (file.getspecialfolderpath ("", "Desktop Folder", false) + "mysubscriptions.opml"))
	<<local (s = file.readwholefile ("Ohio:mysubscriptions.opml"))
	<<s = tcp.httpreadurl ("http://howto.opml.org/dave/newsRiverOrg/podcastReadingList.opml")
	<<getOpmlFeeds (s, @scratchpad.opmlfeeds, @scratchpad.opmllistinfo)



This listing is for code that runs in the OPML Editor environment. I created these listings because I wanted the search engines to index it, so that when I want to look up something in my codebase I don't have to use the much slower search functionality in my object database. Dave Winer.