You are currently viewing a snapshot of www.mozilla.org taken on April 21, 2008. Most of this content is highly out of date (some pages haven't been updated since the project began in 1998) and exists for historical purposes only. If there are any pages on this archive site that you think should be added back to www.mozilla.org, please file a bug.


Example: How to Display the Contents of a Datasource

This was posted by Adam Fletcher (adamf+rdf@csh.rit.edu) to the netscape.public.mozilla.rdf newsgroup.


I am posting an example of how to display all of the resources and literals in an RDF in hopes that others find it useful when they are learning how to deal with RDF. This is pretty much a summary I've what I've come to understand about RDF's in the past week or two. A good bit of this code and understanding came from the RDF In Mozilla FAQ, availabe at http://www.mozilla.org/rdf/doc/faq.html.

I hope this helps some people. I know it has helped me understand RDF and datasources in Mozilla.

I'm going to assume that you've got a XUL template like this:

<tree id='my-id' ... datasources="rdf:null"> <template> ... </template> </tree>

The important thing is to note the datasources="rdf:null". This means we will build our datasources in memory, instead of explicity loading them when the XUL is parsed.

And that this code works. I will also assume you have some RDF that you've written that is syntacticly valid. To help you test & write your RDF, you should check out RDFedt, a piece of windows freeware by Jan Winkler, available from http://www.jan-winkler.de/dev/e_rdfe.htm.

Okay, now that you have some RDF, and some XUL like the above, we will write our Javascript to load the RDF and populate a datasource. This function will take a URI of the RDF, and the ID of the element that has a template associated with it (in the above case, this id would be 'my-id'). This function should be called when you want to populate the template, for example on the onload event of the tree.

// begin example code // globals var myDatasource = null; function loadDatasource(dsURI, elementToAttachToID) { // get the RDF component from XPCOM var RDF = Components .classes["@mozilla.org/rdf/rdf-service;1"] .getService(Components.interfaces.nsIRDFService); // get the datasource from the URI passed to this function myDatasource = RDF.GetDataSource(dsURI); // Datasources don't load right away- they don't block. If you want // to block, look at nsIRDFRemoteDataSource and the Refresh(true) // method. // because they don't block, if we want to know when they are done // loading, we register an observer to watch over it, and // declare callbacks in that observer. The observer code is elswhere // in this source listing // this test code is pretty much verbatim from // http://www.mozilla.org/rdf/doc/faq.html // so props to Chris Waterson for that if (myDatasource.loaded) { consolePrint("the datasource was already loaded!"); } else { consolePrint("the datasource wasn't loaded, but it's loading now!"); // RDF/XML Datasources are all nsIRDFXMLSinks var sink = myDatasource.QueryInterface( Components.interfaces.nsIRDFXMLSink); // Attach the observer to the datasource-as-sink sink.addXMLSinkObserver(Observer); // Now Observer's methods will be called-back as // the load progresses. } // get the element from the ID passed to this function var myElement = document.getElementById(elementToAttachToID); // each element has a database of datasouces // (actually an nsIRDFCompositeDataSource) // we add our datasource to this myElement.database.AddDataSource(myDatasource); // we rebuild the element to make the template rules get parsed myElement.builder.rebuild(); } // Now the observer class // these are all callbacks // we choose just to implement one // again, props to Chris Waterson and the RDF-in-Mozilla FAQ var Observer = { onBeginLoad: function(aSink) {}, onInterrupt: function(aSink) {}, onResume: function(aSink) {}, onEndLoad: function(aSink) { // here is where we deviate from the RDF-In-Mozilla FAQ // we are going to get all the resources // and print out any values in them // for the entire RDF consolePrint("myDatasource -->" + myDatasource + "<--"); var dsResources = myDatasource.GetAllResources(); var thisResource = null; var arcCursor = null; var thisArc = null; while(dsResources.hasMoreElements()) { consolePrint("myDatasource has elements"); thisResource = dsResources.getNext().QueryInterface( Components.interfaces.nsIRDFResource); consolePrint("thisResource --> " + thisResource.Value + " <--"); // okay, ArcLabelsOut will give us all the "arcs", // or resources with children, in this RDF graph arcCursor = myDatasource.ArcLabelsOut(thisResource); // showArcs is the function below. this is a recursive // function, and is where the magic happens showArcs(thisResource, arcCursor); } consolePrint("done!"); }, onError: function(aSink, aStatus, aErrorMsg) { consolePrint("error! " + aErrorMsg); } }; // the magic function // we will travese through the arcs // and if they have RDFNodes at the end, print out the value // but if they are resources, call this function again until we hit the // the end function showArcs(thisResource, arcCursor) { while(arcCursor.hasMoreElements()) { consolePrint("arcCursor has elements:"); thisArc = arcCursor.getNext().QueryInterface( Components.interfaces.nsIRDFResource); consolePrint("thisArc --> " + thisArc.Value + " <--"); // you should look in the IDL for nsIRDFDataSource // Honestly, I had tried this with GetSources, but that does not // work, and I don't know why. arcTargets = myDatasource.GetTargets( thisResource, thisArc, true ); while(arcTargets.hasMoreElements()) { consolePrint("arcTargets has elements"); thisTarget = arcTargets.getNext(); // we are looking to catch the NO_INTERFACE exceptoin // if we cannot attach the nsIRDFLiteral interface // we know we have an nsIRDFResource, and should look at // that resource's arcs. try { thisTarget.QueryInterface( Components.interfaces.nsIRDFLiteral); consolePrint("thisTarget --> " + thisTarget.Value + " <--"); } catch(e) { newArcCursor = myDatasource.ArcLabelsOut( thisTarget); // recurse down these new arcs showArcs(thisTarget, newArcCursor); } } } } // that's all folks