Retrieving Literals
The triples used so far have all had variables in both the subject and object. However, a string value may be used instead. Since the subject of an RDF arc is always a resource, the subject may be a resource URI. The object attribute may be a resource URI or a literal value. Using a literal as the object of a triple is a common way to filter out specific items. For instance, if items were identified with a type, the data could be filtered to include only items of a particular type.
Here is an example triple that we could use in the photos example:
<query> <content uri="?start"/> <member container="?start" child="?photo"/> <triple subject="?photo" predicate="http://purl.org/dc/elements/1.1/title" object="Canal"/> </query>
This new triple has a static value for the object attribute instead of a variable reference. You might be able to guess that it will cause a match for only one of the photos, the Canal photo. The others won't be able to match when evaluating the triple. To look closer, here is the data network after only the member has been evaluated:
(?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/palace.jpg) (?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg) (?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/obselisk.jpg)
When evaluating the triple, the template builder will iterate over the three potential results found so far. For the first result, the value of the ?photo variable 'http://www.xulplanet.com/ndeakin/images/t/palace.jpg' will be used as the subject, the predicate will be 'http://purl.org/dc/elements/1.1/title', and the object will be 'Canal'. Since there are no variables to fill into the triple, the builder will just confirm that such a triple exists in the datasource. The triple doesn't exist for the first result since the title for the first photo is 'Palace from Above', so the potential result will be removed from the data. For the second result, such an arc does exist, so the result is kept. Like the first result, there is no arc for the third photo, so it is also removed.
The resulting data will look like the following:
(?start = http://www.xulplanet.com/rdf/myphotos, ?photo = http://www.xulplanet.com/ndeakin/images/t/canal.jpg)
Here is the example.
Naturally, we will need to add a binding for the ?title variable if we wish to display it, or we could just hardcode it since we know the value will be 'Canal'. Usually you won't be filtering on a title though--you would instead filter on a value that acts like a type.
There has to be at least one variable used in a triple in either the subject or the object attributes, or both. You can't have a triple with no variables. That's not an issue though, since it wouldn't be particularly useful. Also, you cannot use a variable in the predicate. Only the subject and object attributes may have variables. Another thing that you cannot have is a triple where both variables would be unknown as in the following:
<query> <content uri="?start"/> <member container="?start" child="?photo"/> <triple subject="?category" predicate="http://purl.org/dc/elements/1.1/title" object="?title"/> </query>
In this case when the template builder gets to the triple, neither the ?category nor the ?title variables can be filled in so the builder doesn't know what to generate. The builder won't generate any output in this situation.
The member tag must have variables for both the container and child attributes. It wouldn't be very common to filter for a specific child anyway.
Source Navigation
Triples may also be used to navigate up the graph as well as downwards, following the graph arrows in the reverse direction. For instance, in the original example, we could start at node D and navigate upwards to A and C. The syntax for the triple is the same except that the known variable should be placed in the triple's object attribute and the unknown variable should be placed in the triple's subject variable.
<query> <content uri="?start"/> <triple subject="?relateditem" predicate="http://www.xulplanet.com/rdf/relatedItem" object="?start"/> </query>
The triple is evaluated in the same manner except that the value of the object can be filled in with the value of the ?start variable. The RDF graph is examined for an arrow pointing in to the node instead of out. In the photos example, we might wish to categorize each photo into several categories. One possibility is to just add another predicate for each photo with a literal value set to the category. Or, we could use a resource for each category. This will allow us to associate additional properties to each category and more easily navigate the graph in a template. In this case, we will categorize each photo by country where the photo was taken using a country predicate.
<?xml version="1.0"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:r="http://www.xulplanet.com/rdf/"> <rdf:Seq rdf:about="http://www.xulplanet.com/rdf/myphotos"> <rdf:li rdf:resource="http://www.xulplanet.com/ndeakin/images/t/palace.jpg"/> <rdf:li rdf:resource="http://www.xulplanet.com/ndeakin/images/t/canal.jpg"/> <rdf:li rdf:resource="http://www.xulplanet.com/ndeakin/images/t/obelisk.jpg"/> </rdf:Seq> <rdf:Description rdf:about="http://www.xulplanet.com/ndeakin/images/t/palace.jpg" dc:title="Palace from Above"> <r:country resource="http://www.daml.org/2001/09/countries/iso#IT"/> </rdf:Description> <rdf:Description rdf:about="http://www.xulplanet.com/ndeakin/images/t/canal.jpg" dc:title="Canal"> <r:country resource="http://www.daml.org/2001/09/countries/iso#NL"/> </rdf:Description> <rdf:Description rdf:about="http://www.xulplanet.com/ndeakin/images/t/obelisk.jpg" dc:title="Obelisk"> <r:country resource="http://www.daml.org/2001/09/countries/iso#IT"/> </rdf:Description> <rdf:Description about="http://www.daml.org/2001/09/countries/iso#IT" dc:title="Italy"/> <rdf:Description about="http://www.daml.org/2001/09/countries/iso#NL" dc:title="Netherlands"/> </rdf:RDF>
A new Country predicate has been added to each photo pointing to another resource. Note that this predicate uses a new namespace so it is declared on the root RDF element. The titles of the two countries are defined near the end of the RDF data. Now that we have countries for each photo, instead of starting at the node 'http://www.xulplanet.com/rdf/myphotos', we could start at a country resource and look for all photos that point to that country. The ref attribute will need to be changed to point to the country resource rather than the Seq container of photos.
<hbox datasources="template-guide-ex2.rdf" ref="http://www.daml.org/2001/09/countries/iso#IT">
In this example, three triples will be used.
<query> <content uri="?start"/> <triple subject="?start" predicate="http://purl.org/dc/elements/1.1/title" object="?countrytitle"/> <triple subject="?photo" predicate="http://www.xulplanet.com/rdf/country" object="?start"/> <triple subject="?photo" predicate="http://purl.org/dc/elements/1.1/title" object="?title"/> </query>
The first triple is used to get the title for the country. There is only one potential result at this point, the starting node which is 'http://www.daml.org/2001/09/countries/iso#IT'. After the first triple is examined, the data network will look like the following:
(?start = http://www.daml.org/2001/09/countries/iso#IT, ?countrytitle = Italy)
Only one result is present since there is only one title available. The second triple is the more interesting one. It is used to look up nodes that have a Country predicate pointing in. It may be difficult to tell whether the builder will look for arcs pointing out from a node or into a node just by looking at the triple
element. The template builder doesn't know this either until the triple is evaluated and variable substitution is done. Here, the value of the ?start variable is already known for the potential result, so it will be filled in. However, the value of the ?photo variable is not known. Since the object is known and the subject is not, the builder knows to look for a predicate pointing in to a node. There are two photos in the RDF datasource that point to the node 'http://www.daml.org/2001/09/countries/iso#IT', so the existing result will be copied for these two photos. The resulting data after the second triple will look like this:
(?start = http://www.daml.org/2001/09/countries/iso#IT, ?countrytitle = Italy, ?photo = http://www.xulplanet.com/ndeakin/images/t/palace.jpg) (?start = http://www.daml.org/2001/09/countries/iso#IT, ?countrytitle = Italy, ?photo = http://www.xulplanet.com/ndeakin/images/t/obselisk.jpg)
The third triple just grabs the title from the photo as previous examples did, adding a value for the ?title variable for each photo. We can then display these results using the following action body.
<vbox uri="?photo" class="box-padded"> <image src="?photo"/> <label value="?title"/> <label value="Country: ?countrytitle"/> </vbox>
A label for the country will be displayed as well. Naturally, it will have the same value for every photo. Some padding has been added around each photo using the 'box-padded' class. Here is the example.
By carefully defining the RDF graph and using the right triples we can usually navigate to any part of the RDF data that is necessary in order to get the right results. Usually, however you will want to iterate only over the children of a node using a member
tag and instead use a triple
or binding
for each predicate of each child that you wish to display. This is the way that the template system was originaly designed to be used and many of the datasources used by Firefox and other Mozilla products work with datasources in this way.
Retrieving Parents
A very uncommon form of navigation you can also do is to navigate upwards using a member
tag, that is to get all the parents of a node, as in this example:
<query> <content uri="?start"/> <member container="?parent" child="?start"/> </query>
This might be used, for instance, to start at a particular photo and find all of the containers that it is inside.