Containment Properties

So far, we've seen how the simple query syntax can generate results from the children of an RDF container. However, the simple query syntax may also iterate over a single predicate pointing out of a resource, rather than use the children. This allows you to iterate over a non-container. To do this, use the containment attribute on the root node, set to the predicate to iterate over.

Let's look back at the very first example again. It doesn't have any containers, but we may want to iterate over the relatedItem predicate using the simple query syntax. We can add the containment attribute to do this.

<vbox datasources="template-guide-ex1.rdf"
         ref="http://www.xulplanet.com/rdf/A"
         containment="http://www.xulplanet.com/rdf/relatedItem">
  <template>
    <rule>
      <label uri="rdf:*" value="rdf:*"/>
    </rule>
  </template>
</vbox>

Instead of iterating over a container, this example iterates over a specific predicate. This attribute is useful when the RDF data is structured in such a way that an RDF container isn't used.

The builder treats the predicate in the containment attribute as an indicator that an element is a container. If the starting node (or ref) has that predicate as one of its triples in the RDF data, the builder will use it in addition to checking if it is a container. Note the distinction here. The containment attribute doesn't replace the existing container checking. If the resource 'http://www.xulplanet.com/rdf/A' was also an RDF Seq with some children, then those children would also be added to the results. This next example demonstrates this. The only difference between this and the previous example is a a couple of additional lines added to the RDF/XML:

<rdf:Seq rdf:about="http://www.xulplanet.com/rdf/A">
  <rdf:li rdf:resource="http://www.xulplanet.com/rdf/E"/>
  <rdf:li rdf:resource="http://www.xulplanet.com/rdf/F"/>
</rdf:Seq>

The effect is that there are five results instead of three. Three generated via the use of the containment attribute, and two generated because the starting resource is a container with two children. Effectively, the containment attribute allows you to specify additional predicates that provide children.

You can specify multiple predicates in the containment attribute by separating them with spaces. Each will be applied in sequence.

The containment attribute also applies to member tests when using the extended template syntax. That is, in addition to iterating over the children, it will iterate over the predicates listed in the containment attribute. For example, the following is equivalent to the previous example, except that the full query syntax is used.

<vbox datasources="template-guide-ex3.rdf"
         ref="http://www.xulplanet.com/rdf/A"
         containment="http://www.xulplanet.com/rdf/relatedItem">
  <template>
    <query>
      <content uri="?start"/>
      <member container="?start" child="?child"/>
    </query>
    <action>
      <label uri="?child" value="?child"/>
    </action>
  </template>
</vbox>

Try this example. What happens is that the builder generates additional possible values for the ?child variable, so it creates an additional result for each one.