The datasource associated with the template can be retrieved using the element's "database" property. It implements the nsIRDFCompositeDataSource interface. Since this is a composite datasource, it may contain more than one datasource. These may be listed in the datasources attribute separated by spaces. For example:

<vbox datasources="template-guide-photos5.rdf template-guide-streets.rdf">

Sometimes, you will want to calculate the datasource to be used and attach it to the template later. You can do this using the composite datasource's AddDataSource method. You can add as many datasources as you wish, and you can remove them using the RemoveDataSource method. A common pattern is to use the following:

var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].
            getService(Components.interfaces.nsIRDFService);
var ds = RDF.GetDataSource("http://www.xulplanet.com/ndeakin/tests/xul/template-guide-streets.rdf");
var tree = document.getElementById("theTree");
tree.database.AddDataSource(ds);
tree.builder.rebuild();

This is the typical way to add a datasource to an element, in this case to the tree with the id "theTree". The datasource is retrieved using the RDF service's GetDataSource method. After adding a datasource, the tree builder's rebuild method is invoked to rebuild the template with the new data. This doesn't happen automatically when you add the datasource, which is useful, since you will often want to add or remove other datasources at the same time.

The composite datasource can only be accessed from privileged code, regardless of what datasources it contains. Fortunately in this situation, you can just set the datasources attribute (or the corresponding property) to the datasources that you want. For instance:

var tree = document.getElementById("theTree");
tree.datasources = "template-guide-photos5.rdf template-guide-streets.rdf";

This will also change the datasources used. In this case, the template will be rebuilt automatically as you can set all of the datasources at once with this method of changing datasources. So you don't need to call the rebuild method. You can also do the same with the ref attribute (or the ref property) and the template will be rebuilt automatically. In the example above, there will be two datasources attached to the tree. They will both be loaded and the template reconstructed. Note that if one of the datasources is already loaded it will not be loaded again. This is convenient when you want to simply add a new datasource to an existing template without reloading existing data. If you do want to reload the data, you can call the builder's refresh method:

tree.builder.refresh();

This will reload the datasource attached to the template. If there is more than one datasource, as above, all of them will be reloaded. Due to the nature of the way templates are updated, you don't usually need to rebuild a template after a refresh call, although there may situtations where this will be necessary.

If you do plan on determining the datasources dynamically, it is common to start with an empty datasource using the special URI "rdf:null".

<tree datasources="rdf:null" ref="http://www.xulplanet.com/rdf/myphotos">

This will create a composite datasource with no datasources in it. This syntax is necessary as otherwise you wouldn't be able to specify a value for the datasources attribute, and a template builder would not be attached to the element. In a chrome context, the datasource rdf:local-store is always included even if you don't specify it. This is something to watch out for if you are going to be manipulating the composite datasource.

One more note: the datasources attribute may use either absolute or relative URLs. Relative URLs are relative to the XUL document the corresponding element is in. The RDF service's GetDataSource method however, only accepts absolute URLs. So you will need to use the full path in this situation.