<?xml version='1.0' encoding='iso-8859-1'?><?xml-stylesheet type='text/xsl' href='http://w3future.com/w3f/w3f.xsl' ?>
<html xmlns="http://www.w3.org/2002/06/xhtml2" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xf="http://www.w3.org/2002/xforms/cr" xml:lang="en" xml:base="http://w3future.com/html/opmlloader.txt">
<head>
<title>Loading OPML documents</title>
<style type='text/css'>.details {display: none;}</style><style type='text/css'>@import 'opmlloader.css';</style></head>
<body>
<section id="content">
	<h>Loading OPML documents</h>
	<p>Using server side XML parsing</p>
	<section id="note">
		<h3>Note</h3><p>Some documents can take a long time to load.</p><h3>XML parsing</h3><p>In the <a href='opmlloaderIE5.html'>previous version</a> I used client side XML parsing. But all the different versions of MS's XML parser caused some problems, and IE6 does not allow script to load resources from other domains by default.</p><h>Last Update</h>
		<p>10/16/2005; 1:23:09 AM</p>
		<p id="alternates" class="buttons">
			<l href="http://w3future.com/html/opmlloader.xml?notransform" rel="alternate" type="application/xml" title="See this web page with XHTML 2.0 technology."><span>Try</span> XHTML 2.0</l>
			<l href="view-source:http://w3future.com/html/opmlloader.xml?notransform" title="View the XHTML 2.0 source of this page."><span>Src</span> XHTML 2.0</l>
			<l href="http://w3future.com/tools/xr.pl?xr=http://w3future.com/xr/w3f.xml&amp;xml=http://w3future.com/html/opmlloader.xml%3Fnotransform" rel="meta" type="application/rdf+xml" title="RDF metadata"><span>RDF</span> Metadata</l>
		</p>
		<xi:include href="http://w3future.com/w3f/buttons.xml" />
	</section>	<script type="text/javascript"><!--
		
		function w3fNode(o) {
			if (o) this.set(o);
		};
		w3fNode.prototype={
			set:function(o) {
				for (var i in o) this[i]=o[i];
			},
			expand:function(redraw) {
				var target=document.getElementById('childrenOf'+this.id);
				if (!target.innerHTML||redraw) {
					var c='';
					for (var i=0;i<this.childNodes.length;i++) {
						c+='\r<tr><td>'+this.childNodes[i].render()+'</td></tr>';
					}
					c='<table cellspacing=0 cellpadding=0>'+c+'</table>';
					target.innerHTML=c;
					if (this.loadUrl) window.setTimeout('nc.bag["'+this.id+'"].insertFile()',1)
					else if (this.loadRelated) window.setTimeout('nc.bag["'+this.id+'"].insertRelated()',1)
					this.loadUrl=this.loadRelated=false;
				}
				target.style.display='';
				document.getElementById('openclose'+this.id).innerHTML='<span class="openclose" onclick="nc.bag[\''+this.id+'\'].collapse()">v</span>';
			},
			collapse:function() {
				var target=document.getElementById('childrenOf'+this.id);
				target.style.display='none';
				document.getElementById('openclose'+this.id).innerHTML='<span class="openclose" onclick="nc.bag[\''+this.id+'\'].expand()">&gt;</span>';
			},
			insertFile:function() {
				this.loadXML(this.props.url||this.props.xmlUrl);
			},
			insertRelated:function() {
/*				var s=new w3f_XMLRPCService('http:/'+'/google.xmlrpc.com/RPC2');
				var node=this;
				s.onload=function () {
					if (this.error) {
						alert(this.error);
					} else {
						var results=this.result.resultElements;
						var j=0;
						for (var i in results) {
							var res=results[i];
							node.childNodes[j++]=nc.createNode({
								text:res.title||res.URL,
								props:{
									url:res.URL,
									type:'link'
								}
							});
						}
						node.expand(true);
					}
				};
				s.call('googleGateway.search',["related:"+this.props.url, 0, 10, "", "", false, "latin1", "latin1", "6ycnFAZiVyxI5J5Xu+9s6zlKNGx5au02"]);*/
				var s=new w3f_XMLDocument();
				var node=this;
				s.onload=function () {
					if (this.documentElement.nodeName=='!error') {
						alert('Error parsing '+this.url+' at line '+this.documentElement.attributes.line+': '+this.documentElement.attributes.code);
						return;
					}
					var results=this.getSimpleTree().GoogleSearchResult.resultElements.item;
					var j=0;
					for (var i=0;i<results.length;i++) {
						var res=results[i];
						node.childNodes[j++]=nc.createNode({
							text:res.title['#text']||(''+res.URL),
							props:{
								url:''+res.URL,
								type:'link'
							}
						});
					}
					node.expand(true);
				};
				s.load('http:/'+'/xoomle.dentedreality.com.au/search/?key=6ycnFAZiVyxI5J5Xu%2B9s6zlKNGx5au02&q='+escape("related:"+this.props.url));
			},
			loadXML:function(url) {
				var doc=new w3f_XMLDocument();
				doc.rootNode=this;
				doc.onload=function() {
					if (this.documentElement.nodeName=='!error') {
						alert('Error parsing '+this.url+' at line '+this.documentElement.attributes.line+': '+this.documentElement.attributes.code);
					}
					if (this.documentElement.nodeName.toLowerCase()=='opml') 
						this.rootNode.parseOPML(this);
					else
						this.rootNode.parseXMLFragment(this.documentElement);
					this.rootNode.expand(true);
				}
				doc.load(url);
			},
			parseOPML:function(doc) {
				var root=doc.documentElement;
				this.parseOPMLFragment(root.childNodes.item(1));
				var head=root.childNodes.item(0);
				var nl=head.childNodes;
				for (var i=0;i<nl.length;i++) {
					var n=nl.item(i);
					if (n.nodeType!=1) continue; // only elements
					this.props[n.nodeName]=n.text;
				}
			},
			parseOPMLFragment:function(fragment) {
				this.childNodes=[];
				this.props={};
				var attrs=fragment.attributes;
				for (var i=0;i<attrs.length;i++) {
					var a=attrs[i];
					this.props[a.nodeName]=a.nodeValue;
				}
				this.text=''+this.props.text;//fixText(''+this.props.text);
				var l=0;
				var nl=fragment.childNodes;
				for (var i=0;i<nl.length;i++) {
					var n=nl.item(i);
					if (n.nodeType!=1) continue; // only elements
					var c=this.childNodes[l++]=nc.createNode();
					c.parseOPMLFragment(n);
				}
			},
			parseXMLFragment:function(fragment) {
				this.set({childNodes:[],text:'&lt;'+fragment.nodeName});
				var attrs=fragment.attributes;
				for (var i=0;i<attrs.length;i++) {
					var a=attrs[i];
					this.text+=' '+a.nodeName+'="'+a.nodeValue+'"';
				}
				this.text+='&gt;';
				var l=0;
				var nl=fragment.childNodes;
				for (var i=0;i<nl.length;i++) {
					var n=nl.item(i);
					var c=this.childNodes[l++]=nc.createNode();
					switch (n.nodeType) {
						case 1:/*element*/c.parseXMLFragment(n);break;
						case 3:/*text*/c.set({text:n.nodeValue});break;
						default:c.set({text:'NodeType: '+n.nodeType});break;
					}
				}
			},
			render:function() {
				var s='';
				if (this.props) {
					switch (this.props.type) {
						case 'link':
					 	case 'file':
							var url=this.props.url;var dotPos=url.lastIndexOf('.');
							var ext=url.substr(dotPos).toLowerCase();
							if (ext=='.opml'||ext=='.xml') {
								this.childNodes=[nc.createNode({text:'Loading...'})];
								this.loadUrl=true;
								s=this.text+' (<A href="'+url+'">link</A>)';
							} else {
								this.childNodes=[nc.createNode({text:'Loading related sites...'})];
								this.loadRelated=true;
								s='<A href="'+url+'">'+this.text+'</A>';
							}
							break;
						case 'folder':
							s=this.text;
							break;
						case 'rss':
							this.childNodes=[nc.createNode({text:'Loading...'})];
							this.loadUrl=true;
							s=this.text+' (<A href="'+this.props.htmlUrl+'">html</A>,<A href="'+this.props.xmlUrl+'">xml</A>)';
							break;
						case 'opmlroot':
							this.childNodes=[nc.createNode({text:'Loading...'})];
							this.loadUrl=true;
							s=this.props.url;
							break;
						default:
							if (this.text) s=this.text;
							break;
					}
				} else if (this.text) s=this.text;
				var a='';
				if (this.props) for (var p in this.props) {
					if (p=='text') continue;
					a+='<TR><TH class="props">'+p+'</TH><TD class="border"><INPUT class="props" readonly value="'+this.props[p]+'" size="60"></TD></TR>';
				}
				if (a) {
					s+='<SPAN class="details"><DIV class="indent"><TABLE class="border" cellspacing=0 cellpadding=0>'+a+'</TABLE></DIV></SPAN>';
				}
				if (this.childNodes&&this.childNodes.length) {
					s='<SPAN id="openclose'+this.id+'"><SPAN class="openclose" onclick="nc.bag[\''+this.id+'\'].expand()">&gt;</SPAN></SPAN>&nbsp;'+s;
					s+='<DIV id="childrenOf'+this.id+'" style="display:none" class="indent"></DIV>';
				} else s='<SPAN class="text"><span class="leaf">&gt;</span>&nbsp;'+s+'</SPAN>';
				return s;
			}
		}
		
		function NodeContainer() {};
		NodeContainer.prototype={
			bag:{},
			counter:0,
			createNode:function(o) {
				var n=new w3fNode(o);
				n.id=this.counter++;
				this.bag[n.id]=n;
				return n;
			}
		}
		var nc=new NodeContainer();
		 
		function loadXML(url) {
			location.replace('#'+url);
			var doc=nc.createNode();
			doc.props={url:url,type:'opmlroot'};
			document.getElementById('OPMLDiv').innerHTML=doc.render();
			doc.expand(true);
		}
		
		function loadRel(url) {
			location.replace('#rel='+url);
			var doc=nc.createNode({
				text:url,
				props:{url:url,type:'link'}
			});
			document.getElementById('OPMLDiv').innerHTML=doc.render();
			doc.expand(true);
		}
		
		function fixText(s) {
			return s.replace(/</g,'&lt;');
		}
		
		function err(e,s) {
		  for (var i in e) {
		    s+='\n'+i+': '+e[i];
		  }
		  alert(s);
		}
		
		function loadHash() {
			var h=location.hash;
			if (h.length<2) return;
			h=h.substr(1);
			if (h.substr(0,4)=='rel=') {
				h=h.substr(4)
				document.forms['loader'].url.value=h;
				loadRel(h);
			} else {
				document.forms['loader'].url.value=h;
				loadXML(h);
			}
		}
		document.body.setAttribute("onload","loadHash()");
		document.body.onload=new Function("", "loadHash()");
		
	//-->
	</script>
<section>
<h>Enter URL of OPML document</h>
<p>Or drag one of the examples on the left to the input field.</p>
<form onsubmit="return false;" id="loader" action="">
<p><input type="text" style="width:80%" name="url" value="" /></p>
<table><tr><td>
<button style="width:15em" onclick="loadXML(document.forms['loader'].url.value)">Load and Render</button>
</td><td> or </td><td>
<button style="width:15em" onclick="loadRel(document.forms['loader'].url.value)">Show related pages</button>
</td></tr></table>
<p><input type="checkbox" name="showdetails" id="showdetails" onclick="this.blur()" onchange="var s=document.styleSheets[0].disabled=this.checked;" />Show Node Properties</p>
</form>
</section>
<section style="clear:both">
<h>Result</h>
<div id="OPMLDiv"></div>
</section>
<section>
<h>Details</h>
<p>The XML files are parsed on the server. It generates javascript data.
This data is then loaded into the page through an IFRAME.
When a branch is encountered with type="file" or type="link", and the url ends with ".opml" or ".xml", or with
type="rss" then the file is automatically loaded into the tree.</p>
<p>When you expand links to html pages, the 
<a href="http://www.xmlrpc.com/googleGateway">Google XML-RPC gateway</a> is used to render the related sites. This is an
<a href="http://scriptingnews.userland.com/backissues/2002/04/18#l43b8e5829867ac5f3b79415b253dd29a">idea by Dave Winer</a>.</p>
</section>
<section>
<h>Download</h>
<p><a href="/tools/opmlloader.zip">Click here to download.</a> It contains all files to get this to run, and should be installed on a PHP server.</p>
</section>
<script src="/tools/xmlload.js" type="text/javascript"></script>
<script src="/tools/xmlrpc.js" type="text/javascript"></script>
<xi:include href="http://w3future.com/tools/rdf.php?about=http://w3future.com/html/opmlloader.txt" /></section>
<section id="navigation"><xi:include href="http://w3future.com/w3f/sections.xml" /></section>
<section id="sidebar"><xi:include href="http://w3future.com/weblog/sidebars/opmlloader.opml" /></section>
</body>
</html>
