Diff for /books/www/chapters/ch10.html between versions 1.2 and 1.14

version 1.2, 2002/09/23 15:23:31 version 1.14, 2003/03/29 10:13:48
Line 1 Line 1
<HTML>    <link rel="prev" href="http://books.mozdev.org/chapters/ch09.html" />
<HEAD><TITLE>Chapter 10</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 10</H2>    <link rel="next" href="http://books.mozdev.org/chapters/ch11.html" />
<H1><A NAME="77061"></A> RDF, RDF Tools, and the Content Model</H1> 
<P><A HREF="ch09.html#77034">Chapter 9</A> introduced the Resource Description Framework (RDF) as the basis for building display data in the  
interface, where XUL templates take RDF-based data and transform it into regular widgets. But RDF is used in many other more subtle ways in Mozilla. In fact, it is the technology Mozilla uses for much of its own internal data handling and manipulation. 
<P>RDF is, as its name suggests, a framework for integrating many types of data that go into the browser, including bookmarks, mail messages, user profiles, IRC channels, new Mozilla applications, and your collection of sidebar tabs. All these items are sets of data that RDF represents and incorporates into the browser consistently. RDF is used prolifically in Mozilla, which is why this chapter is so dense. 
<P>This chapter introduces RDF, provides some detail about how Mozilla uses RDF for its own purposes, and describes the RDF tools that are available on the Mozilla platform. The chapter includes information on special JavaScript libraries that make RDF processing much easier, and on the use of RDF in manifests to represent JAR file contents and cross-platform installation archives to Mozilla. 
<P>Once you understand the concepts in this chapter, you can make better use of data and metadata in your own application development. 
<H2><A NAME="77062"></A> RDF Basics</H2> 
<P>RDF has two <!--INDEX RDF (Resource Description Framework):overview -->  parts: the <I>RDF Data Model</I> and the <I>RDF Syntax</I> (or Grammar). The RDF Data Model is a graph with nodes and arcs, much like other data graphs. More specifically, it's a <I>labeled-directed</I> graph. All nodes and arcs have some type of label (i.e., an identifier) on them, and arcs point only in one direction. 
<P>The RDF Syntax determines how the RDF Data Model is represented, typically as a special kind of XML. Most XML specifications define data in a tree-like model, such as XUL and XBL. But the RDF Data Model cannot be represented in a true tree-like structure, so the RDF/XML syntax includes properties that allow you to represent the same data in more than one way: elements can appear in different orders but mean the same thing, the same data can be represented as a child element or as a parent attribute, and data have indirect meanings. The meaning is not inherent in the structure of the RDF/XML itself; only the relationships are inherent. Thus, an RDF processor must make sense of the represented RDF data. Fortunately, an excellent RDF processor is integrated into Mozilla. 
<H3><A NAME="77063"></A> RDF Data Model</H3> 
<P>Three  <!--INDEX RDF (Resource Description Framework):data model -->  <!--INDEX data model (RDF) --> different types of RDF objects are the basis for all other RDF concepts: <I>resources</I>, <I>properties</I>, and <I>statements</I>. Resources  <!--INDEX resources:RDF --> are any type of data described by RDF. Just as an English sentence is comprised of subjects and objects, the resources described in RDF are typically subjects and objects of RDF statements. Consider this example: 
<BLOCKQUOTE>Eric wrote a book.</BLOCKQUOTE> 
<P><I>Eric</I> is the subject of this statement, and would probably be an RDF resource in an RDF statement. <I>A book</I>, the object, might also be a resource because it represents something about which we might want to say more in RDF-for example, the book is a computer book or the book sells for twenty dollars. A property  <!--INDEX properties:RDF --> is a characteristic of a resource and might have a relationship to other resources. In the example, the book was written by Eric. In the context of RDF, <I>wrote</I> is a property of the <I>Eric</I> resource. An RDF statement is a resource, a property, and another resource grouped together. Our example, made into an RDF statement, might look like this: 
<BLOCKQUOTE>(Eric) wrote (a book)</BLOCKQUOTE> 
<P>Joining RDF statements makes an entire RDF graph. 
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER> 
<P>We are describing the RDF data model here, not the RDF syntax. The RDF syntax uses XML to describe RDF statements and the relationship of resources.<P></BLOCKQUOTE> 
<P>As mentioned in the introduction, the RDF content model is a <I> <!--INDEX labeled-directed graphs (RDF) --> labeled-directed </I>graph, which means that all relationships expressed in the graph are unidirectional, as displayed in <A HREF="#77002">Figure 10-1</A>. 
<P><CENTER><IMG SRC="foo.gif"></CENTER> 
<P><I>Figure 10-1: <A NAME="77002"></A></I> 
<I>Simple labeled-directed graph</I> 
   
<P>A resource can contain either a URI or a literal. The root resource might have a  <!--INDEX URIs (Universal Resource Identifiers):RDF --> URI, for example, from which all other resources in the graph descend. The RDF processor continues from the root resource along its properties to other resources in the graph until it runs out of properties to traverse. RDF processing terminates at a <!--INDEX literals:RDF -->  literal, which is just what it sounds like: something that stands only for itself, generally represented by a string (e.g., "book," if there were no more information about the book in the graph). A literal resource contains only non-RDF data. A literal is a terminal point in the RDF graph.    <style type="text/css">
<P>For a resource to be labeled, it must be addressed through a universal resource identifier (URI). This address must be a unique string that designates what the resource is. In practice, most resources don't have identifiers because they are not nodes on the RDF graph that are meant to be accessed through a URI. <A HREF="#77004">Figure 10-2</A> is a modified version of <A HREF="#77002">Figure 10-1</A> that shows <I>Eric</I> as a resource identifier and <I>book</I> as a literal.      div.c22 {text-align: center}
<P><CENTER><IMG SRC="foo.gif"></CENTER>      div.c21 {font-weight: bold; text-align: center}
<P><I>Figure 10-2: <A NAME="77004"></A></I>    </style>
<I>Resource to literal relationship</I>
    <h2>Chapter 10</h2>
<P>Resources can have any number of properties, which themselves differ. In <A HREF="#77004">Figure 10-2</A>, <I>wrote</I> is a property of <I>Eric</I>. However, resources can also have multiple properties, as shown in <A HREF="#77006">Figure 10-3</A>.    <h1><a name="77061"></a> RDF, RDF Tools, and the Content
<P><CENTER><IMG SRC="foo.gif"></CENTER>    Model</h1>
<P><I>Figure 10-3: <A NAME="77006"></A></I>    <p><a href="ch09.html#77034">Chapter 9</a> introduced the
<I>RDF Graph with five nodes</I>    Resource Description Framework (RDF) as the basis for building
    display data in the interface, where XUL templates take
<P>The RDF graph in <A HREF="#77006">Figure 10-3</A> has five nodes, two resources, and three literals. If this graph were represented in XML, it would probably have three different XML namespaces inside of it: RDF/XML, a <I>book</I> XML specification, and a <I>computer</I> XML specification. In English, the graph in <A HREF="#77006">Figure 10-3</A> might be expressed as follows:    RDF-based data and transform it into regular widgets. But RDF
<BLOCKQUOTE>Eric wrote a book of unknown information. Eric's computer is 700 MHz and has an Athlon CPU.</BLOCKQUOTE>    is used in many other more subtle ways in Mozilla. In fact, it
<P>Note that if Eric wrote a poem and a book, it would be possible to have two <I>wrote</I> properties for the same resource. Using the same property to point to separate resources is confusing, however. Instead, RDF containers (see the section <A HREF="#77069">"RDF containers</A>," later in this chapter) are the best way to organize data that would otherwise need a single property to branch in this way.    is the technology Mozilla uses for much of its own internal
<H4><A NAME="77064"></A> RDF URIs relating to namespaces</H4>    data handling and manipulation.</p>
<P>The  <!--INDEX RDF (Resource Description Framework):data model:URIs -->  <!--INDEX data model (RDF):URIs -->  <!--INDEX URIs (Universal     <p>RDF is, as its name suggests, a framework for integrating
Resource Identifiers):RDF:namespaces -->  <!--INDEX namespaces:RDF, URIs and --> URIs used in RDF can be part of the element namespace. (See <    many types of data that go into the browser, including
HREF="ch02.html#77053">"The XUL Namespace" in Chapter 2</A> and in <A HREF="ch07.html#77031">"Namespaces and XBL" in Chapter 7</A> for more information about XML namespaces.) This use is especially true for properties. Some namespaces can be created from previous examples:    bookmarks, mail messages, user profiles, IRC channels, new
<PRE>xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    Mozilla applications, and your collection of sidebar tabs. All
xmlns:book="<A HREF="http://www.oreilly.com/rdf">http://www.oreilly.com/rdf</A>#"    these items are sets of data that RDF represents and
xmlns:comp="my.computer.hardware#"</PRE>    incorporates into the browser consistently. RDF is used
<P>When you use namespaces, the graph looks much different, as shown in <A HREF="#77008">Figure 10-4</A>.    prolifically in Mozilla, which is why this chapter is so
<P><CENTER><IMG SRC="foo.gif"></CENTER>    dense.</p>
<P><I>Figure 10-4: <A NAME="77008"></A></I>    <p>This chapter introduces RDF, provides some detail about how
<I>Namespaces applied to Figure 10-3</I>    Mozilla uses RDF for its own purposes, and describes the RDF
    tools that are available on the Mozilla platform. The chapter
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    includes information on special JavaScript libraries that make
<P>The resource identifier is often displayed in a URL format too, but it shouldn't use the same namespace URL as the RDF/XML file. The URL typically tries to describe a unique object, such as <I><A HREF="http://my.jar-of-flies.com">http://my.jar-of-flies.com</A></I>.<P></BLOCKQUOTE>    RDF processing much easier, and on the use of RDF in manifests
<H4><A NAME="77065"></A> RDF triples: subject, predicate, and object</H4>    to represent JAR file contents and cross-platform installation
<P>A triple  <!--INDEX statements, RDF, triples -->  <!--INDEX triples:RDF statements -->  <!--INDEX RDF (Resource Description Framework):statements, triples --> is a type of RDF statement. While an RDF statement can be a loose collection of resources, properties, and literals, a triple typically defines a tighter relationship between such elements.    archives to Mozilla.</p>
<P>The first part of a triple is the <I>subject</I>. This part is the resource described by the triple. The second part of the triple is the <I>predicate</I>. This part is a subject's property, a thing that joins it with something else. The third part is the <I>object</I>, which is either a resource or a literal.    <p>Once you understand the concepts in this chapter, you can
<P>RDF triples are significant because their stricter semantics guarantee the relationship between parts. A triple is a more formal version of the RDF statement, which is used more broadly. In <A HREF="#77008">Figure 10-4</A>, all statements are formally subject &gt; predicate &gt; object, so those statements are triples.    make better use of data and metadata in your own application
<H4><A NAME="77066"></A> RDF data model terminology</H4>    development.</p>
<P>When  <!--INDEX RDF (Resource Description Framework):data model:terminology -->  <!--INDEX data model (RDF):terminology --> reading RDF specifications, documentation, examples, and other related material on the Internet, you can encounter a dizzying array of terms that mean the same thing. <A HREF="#77020">Table 10-1</A> should help clarify these different terms. The italicized versions of the synonyms all do not technically mean the same thing, but are loose synonyms whose meanings depend on the context in which they are used.    <h2><a name="77062"></a> RDF Basics</h2>
    <p>RDF has two 
<P><I>Table 10-1: <A NAME="77020"></A></I>    <!--INDEX RDF (Resource Description Framework):overview -->
<I>Synonyms in RDF</I>    parts: the <i>RDF Data Model</i> and the <i>RDF Syntax</i> (or
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Common term</B></TD> <TD><B>  Synonyms</B></TD></TR>    Grammar). The RDF Data Model is a graph with nodes and arcs,
<TR><TD>  Resource</TD>     <TD>  Subject, object</TD></TR>    much like other data graphs. More specifically, it's a
<TR><TD>  Resource identifier</TD>     <TD>  Name, (resource) URI, ID, identifier, URL, label</TD></TR>    <i>labeled-directed</i> graph. All nodes and arcs have some
<TR><TD>  Properties</TD>     <TD>  Attributes</TD></TR>    type of label (i.e., an identifier) on them, and arcs point
<TR><TD>  Statement</TD>     <TD>  Triple, tuple, binding, assertion</TD></TR>    only in one direction.</p>
<TR><TD>  Subject</TD>     <TD>  Source, resource, node, root</TD></TR>    <p>The RDF Syntax determines how the RDF Data Model is
<TR><TD>  Predicate</TD>     <TD>  Arc, (statement) URI, property, atom</TD></TR>    represented, typically as a special kind of XML. Most XML
<TR><TD>  Object</TD>     <TD>  Value, resource, node, literal</TD></TR></TABLE><P>    specifications define data in a tree-like model, such as XUL
    and XBL. But the RDF Data Model cannot be represented in a true
<H3><A NAME="77067"></A> RDF Syntax</H3>    tree-like structure, so the RDF/XML syntax includes properties
<P>Mozilla <!--INDEX RDF (Resource Description Framework):syntax:overview -->  <!--INDEX syntax, RDF:overview -->  uses XML to represent RDF data. In 1999, the W3C defined the RDF/XML specification syntax to make it the most common way RDF is used. The RDF/XML format is sometimes called the RDF serialization syntax because it allows RDF models to be sent easily from one computer application to another in a common XML format.    that allow you to represent the same data in more than one way:
<P>When an application reads an RDF file, the Mozilla RDF processor builds a graphical interpretation in-memory. In this section, you learn how to build an RDF file from scratch and see what the graph looks like after running through Mozilla's RDF processor.    elements can appear in different orders but mean the same
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    thing, the same data can be represented as a child element or
<P><TT>RDF:RDF</TT> is a common namespace representation of RDF/XML data and is the one most frequently used in Mozilla files. However, it can be hard to read, so this chapter uses <TT>rdf:RDF</TT>. The W3C also used <TT>rdf:RDF</TT> in the RDF recommendation document.<P></BLOCKQUOTE>    as a parent attribute, and data have indirect meanings. The
<H4><A NAME="77068"></A> Examining a simple RDF file</H4>    meaning is not inherent in the structure of the RDF/XML itself;
<P>We begin <!--INDEX RDF (Resource Description Framework):syntax:files -->  <!--INDEX syntax, RDF:files -->  <!--INDEX files:RDF:syntax -->  with an example of an RDF file whose basic layout and simple syntax can be a model for the more advanced data introduced later. The RDF file shown in <A HREF="#77026">Example 10-1</A> is a list of three types of "flies," with the context of those "flies" inside a "jar." <A HREF="#77026">Example 10-1</A> also contains a namespace that defines these types of flies and shows the <TT>rdf</TT> and <TT>fly</TT> XML intertwined.    only the relationships are inherent. Thus, an RDF processor
    must make sense of the represented RDF data. Fortunately, an
<P><I>Example 10-1: <A NAME="77026"></A></I>    excellent RDF processor is integrated into Mozilla.</p>
<I>Simple RDF file with "fly" namespace</I>    <h3><a name="77063"></a> RDF Data Model</h3>
<PRE>   &lt;?xml version="1.0"?&gt;    <p>Three 
     <!--INDEX RDF (Resource Description Framework):data model --> 
     <!--INDEX data model (RDF) --> different types of RDF objects
     are the basis for all other RDF concepts: <i>resources</i>,
     <i>properties</i>, and <i>statements</i>. Resources 
     <!--INDEX resources:RDF --> are any type of data described by
     RDF. Just as an English sentence is comprised of subjects and
     objects, the resources described in RDF are typically subjects
     and objects of RDF statements. Consider this example:</p>
     <blockquote>
       Eric wrote a book.
     </blockquote>
     <p><i>Eric</i> is the subject of this statement, and would
     probably be an RDF resource in an RDF statement. <i>A book</i>,
     the object, might also be a resource because it represents
     something about which we might want to say more in RDF-for
     example, the book is a computer book or the book sells for
     twenty dollars. A property <!--INDEX properties:RDF --> is a
     characteristic of a resource and might have a relationship to
     other resources. In the example, the book was written by Eric.
     In the context of RDF, <i>wrote</i> is a property of the
     <i>Eric</i> resource. An RDF statement is a resource, a
     property, and another resource grouped together. Our example,
     made into an RDF statement, might look like this:</p>
     <blockquote>
       (Eric) wrote (a book)
     </blockquote>
     <p>Joining RDF statements makes an entire RDF graph.</p>
     <blockquote>
       <div class="c21">
         NOTE
       </div>
       <p>We are describing the RDF data model here, not the RDF
       syntax. The RDF syntax uses XML to describe RDF statements
       and the relationship of resources.</p>
     </blockquote>
     <p>As mentioned in the introduction, the RDF content model is a
     <i><!--INDEX labeled-directed graphs (RDF) -->
     labeled-directed</i> graph, which means that all relationships
     expressed in the graph are unidirectional, as displayed in <a
     href="#77002">Figure 10-1</a>.</p>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-1: <a name="77002"></a></i> <i>Simple
     labeled-directed graph</i></p>
     <p>A resource can contain either a URI or a literal. The root
     resource might have a 
     <!--INDEX URIs (Universal Resource Identifiers):RDF --> URI,
     for example, from which all other resources in the graph
     descend. The RDF processor continues from the root resource
     along its properties to other resources in the graph until it
     runs out of properties to traverse. RDF processing terminates
     at a <!--INDEX literals:RDF --> literal, which is just what it
     sounds like: something that stands only for itself, generally
     represented by a string (e.g., "book," if there were no more
     information about the book in the graph). A literal resource
     contains only non-RDF data. A literal is a terminal point in
     the RDF graph.</p>
     <p>For a resource to be labeled, it must be addressed through a
     universal resource identifier (URI). This address must be a
     unique string that designates what the resource is. In
     practice, most resources don't have identifiers because they
     are not nodes on the RDF graph that are meant to be accessed
     through a URI. <a href="#77004">Figure 10-2</a> is a modified
     version of <a href="#77002">Figure 10-1</a> that shows
     <i>Eric</i> as a resource identifier and <i>book</i> as a
     literal.</p>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-2: <a name="77004"></a></i> <i>Resource to
     literal relationship</i></p>
     <p>Resources can have any number of properties, which
     themselves differ. In <a href="#77004">Figure 10-2</a>,
     <i>wrote</i> is a property of <i>Eric</i>. However, resources
     can also have multiple properties, as shown in <a href=
     "#77006">Figure 10-3</a>.</p>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-3: <a name="77006"></a></i> <i>RDF Graph with
     five nodes</i></p>
     <p>The RDF graph in <a href="#77006">Figure 10-3</a> has five
     nodes, two resources, and three literals. If this graph were
     represented in XML, it would probably have three different XML
     namespaces inside of it: RDF/XML, a <i>book</i> XML
     specification, and a <i>computer</i> XML specification. In
     English, the graph in <a href="#77006">Figure 10-3</a> might be
     expressed as follows:</p>
     <blockquote>
       Eric wrote a book of unknown information. Eric's computer is
       700 MHz and has an Athlon CPU.
     </blockquote>
     <p>Note that if Eric wrote a poem and a book, it would be
     possible to have two <i>wrote</i> properties for the same
     resource. Using the same property to point to separate
     resources is confusing, however. Instead, RDF containers (see
     the section <a href="#77069">"RDF containers</a>," later in
     this chapter) are the best way to organize data that would
     otherwise need a single property to branch in this way.</p>
     <h4><a name="77064"></a> RDF URIs relating to namespaces</h4>
     <p>The 
     <!--INDEX RDF (Resource Description Framework):data model:URIs -->
     <!--INDEX data model (RDF):URIs --> <!--INDEX URIs (Universal 
     Resource Identifiers):RDF:namespaces --> 
     <!--INDEX namespaces:RDF, URIs and --> URIs used in RDF can be
     part of the element namespace. (See <a href=
     "ch02.html#77053">"The XUL Namespace" in Chapter 2</a> and in
     <a href="ch07.html#77031">"Namespaces and XBL" in Chapter 7</a>
     for more information about XML namespaces.) This use is
     especially true for properties. Some namespaces can be created
     from previous examples:</p>
 <pre>
 xmlns:rdf="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
 xmlns:book="<a href=
 "http://www.oreilly.com/rdf">http://www.oreilly.com/rdf</a>#"
 xmlns:comp="my.computer.hardware#"
 </pre>
     <p>When you use namespaces, the graph looks much different, as
     shown in <a href="#77008">Figure 10-4</a>.</p>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-4: <a name="77008"></a></i> <i>Namespaces
     applied to Figure 10-3</i></p>
     <blockquote>
       <div class="c21">
         NOTE
       </div>
       <p>The resource identifier is often displayed in a URL format
       too, but it shouldn't use the same namespace URL as the
       RDF/XML file. The URL typically tries to describe a unique
       object, such as <i><a href=
       "http://my.jar-of-flies.com">http://my.jar-of-flies.com</a></i>.</p>
     </blockquote>
     <h4><a name="77065"></a> RDF triples: subject, predicate, and
     object</h4>
     <p>A triple <!--INDEX statements, RDF, triples --> 
     <!--INDEX triples:RDF statements --> 
     <!--INDEX RDF (Resource Description Framework):statements, triples -->
     is a type of RDF statement. While an RDF statement can be a
     loose collection of resources, properties, and literals, a
     triple typically defines a tighter relationship between such
     elements.</p>
     <p>The first part of a triple is the <i>subject</i>. This part
     is the resource described by the triple. The second part of the
     triple is the <i>predicate</i>. This part is a subject's
     property, a thing that joins it with something else. The third
     part is the <i>object</i>, which is either a resource or a
     literal.</p>
     <p>RDF triples are significant because their stricter semantics
     guarantee the relationship between parts. A triple is a more
     formal version of the RDF statement, which is used more
     broadly. In <a href="#77008">Figure 10-4</a>, all statements
     are formally subject &gt; predicate &gt; object, so those
     statements are triples.</p>
     <h4><a name="77066"></a> RDF data model terminology</h4>
     <p>When 
     <!--INDEX RDF (Resource Description Framework):data model:terminology -->
     <!--INDEX data model (RDF):terminology --> reading RDF
     specifications, documentation, examples, and other related
     material on the Internet, you can encounter a dizzying array of
     terms that mean the same thing. <a href="#77020">Table 10-1</a>
     should help clarify these different terms. The italicized
     versions of the synonyms all do not technically mean the same
     thing, but are loose synonyms whose meanings depend on the
     context in which they are used.</p>
     <p><i>Table 10-1: <a name="77020"></a></i> <i>Synonyms in
     RDF</i></p>
     <table width="100%" border="1">
       <tr>
         <td><b>Common term</b></td>
         <td><b>Synonyms</b></td>
       </tr>
       <tr>
         <td>Resource</td>
         <td>Subject, object</td>
       </tr>
       <tr>
         <td>Resource identifier</td>
         <td>Name, (resource) URI, ID, identifier, URL, label</td>
       </tr>
       <tr>
         <td>Properties</td>
         <td>Attributes</td>
       </tr>
       <tr>
         <td>Statement</td>
         <td>Triple, tuple, binding, assertion</td>
       </tr>
       <tr>
         <td>Subject</td>
         <td>Source, resource, node, root</td>
       </tr>
       <tr>
         <td>Predicate</td>
         <td>Arc, (statement) URI, property, atom</td>
       </tr>
       <tr>
         <td>Object</td>
         <td>Value, resource, node, literal</td>
       </tr>
     </table>
     <h3><a name="77067"></a> RDF Syntax</h3>
     <p>Mozilla 
     <!--INDEX RDF (Resource Description Framework):syntax:overview -->
     <!--INDEX syntax, RDF:overview --> uses XML to represent RDF
     data. In 1999, the W3C defined the RDF/XML specification syntax
     to make it the most common way RDF is used. The RDF/XML format
     is sometimes called the RDF serialization syntax because it
     allows RDF models to be sent easily from one computer
     application to another in a common XML format.</p>
     <p>When an application reads an RDF file, the Mozilla RDF
     processor builds a graphical interpretation in-memory. In this
     section, you learn how to build an RDF file from scratch and
     see what the graph looks like after running through Mozilla's
     RDF processor.</p>
     <blockquote>
       <div class="c21">
         NOTE
       </div>
       <p><tt>RDF:RDF</tt> is a common namespace representation of
       RDF/XML data and is the one most frequently used in Mozilla
       files. However, it can be hard to read, so this chapter uses
       <tt>rdf:RDF</tt>. The W3C also used <tt>rdf:RDF</tt> in the
       RDF recommendation document.</p>
     </blockquote>
     <h4><a name="77068"></a> Examining a simple RDF file</h4>
     
 <p>We begin 
   <!--INDEX RDF (Resource Description Framework):syntax:files -->
   <!--INDEX syntax, RDF:files -->
   <!--INDEX files:RDF:syntax -->
   with an example of an RDF file whose basic layout and simple syntax can be a 
   model for the more advanced data introduced later. The RDF file shown in <a href="#77026">Example 
   10-1</a> is a list of three types of "flies", with the context of those "flies" 
   inside a "jar." <a href="#77026">Example 10-1</a> also contains a namespace 
   that defines these types of flies and shows the <tt>rdf</tt> and <tt>fly</tt> 
   XML intertwined.</p>
     <p><i>Example 10-1: <a name="77026"></a></i> <i>Simple RDF file
     with "fly" namespace</i></p>
 <pre>
    &lt;?xml version="1.0"?&gt;
    &lt;rdf:RDF     &lt;rdf:RDF
      xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"      xmlns:rdf="<a href=
      xmlns:fly="<A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#"&gt;"http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
     &lt;rdf:Description about="<A HREF="http://my.jar-of-flies.com">http://my.jar-of-flies.com</A>"&gt;      xmlns:fly="<a href=
 "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"&gt;
      &lt;rdf:Description about="urn:root"&gt;
        &lt;fly:types&gt;         &lt;fly:types&gt;
          &lt;rdf:Bag&gt;           &lt;rdf:Bag&gt;
            &lt;rdf:li&gt;             &lt;rdf:li&gt;
Line 97  xmlns:comp="my.computer.hardware#"</PRE> Line 322  xmlns:comp="my.computer.hardware#"</PRE>
          &lt;/rdf:Bag&gt;           &lt;/rdf:Bag&gt;
        &lt;/fly:types&gt;         &lt;/fly:types&gt;
      &lt;/rdf:Description&gt;       &lt;/rdf:Description&gt;
   &lt;/rdf:RDF&gt;</PRE>   &lt;/rdf:RDF&gt;
</pre>
<P><TT> <!--INDEX rdf\:Description element --> &lt;rdf:Description&gt;</TT> is the tag used to outline a resource. <A HREF="#77026">Example 10-1</A> shows how the <TT>about</TT> attribute references the resource identifier and makes this resource unique in the document. Two resources cannot have the same <TT>about</TT> value in a document, just as tags cannot share an <TT>id</TT> in an XML document. Both attributes guarantee the unique nature of each element and relationship.    <p><tt><!--INDEX rdf\:Description element -->
<PRE>&lt;rdf:Description about="<A HREF="http://my.jar-of-flies.com">http://my.jar-of-flies.com</A>"&gt;    &lt;rdf:Description&gt;</tt> is the tag used to outline a
     resource. <a href="#77026">Example 10-1</a> shows how the
     <tt>about</tt> attribute references the resource identifier and
     makes this resource unique in the document. Two resources
     cannot have the same <tt>about</tt> value in a document, just
     as tags cannot share an <tt>id</tt> in an XML document. Both
     attributes guarantee the unique nature of each element and
     relationship.</p>
 <pre>
 &lt;rdf:Description about="urn:root"&gt;
 &lt;fly:types&gt;  &lt;fly:types&gt;
&lt;rdf:Bag&gt;</PRE>&lt;rdf:Bag&gt;
<P><TT><A HREF="http://my.jar-of-flies.com">http://my.jar-of-flies.com</A></TT>, is the subject shown in the previous code snippet. <I>My jar of flies</I> is a resource definition and defines only what <I>flies</I> are inside of the statement. The predicate, which addresses a property in the resource, is defined by the tag <TT>&lt;types&gt;</TT> (of the <TT><A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#</TT> namespace).</pre>
<P>The final part of the statement, the object, is the actual data of the predicate and a container of type bag. The container is an RDF resource that "holds," or points to, a collection of other resources. In the next section, container types are discussed in depth. <A HREF="#77010">Figure 10-5</A> illustrates how the triple originates from the root subject and includes the container object.    
<P><CENTER><IMG SRC="foo.gif"></CENTER><p><tt>urn:root</tt>, is the subject shown in the previous code snippet. It is 
<P><I>Figure 10-5: <A NAME="77010"></A></I>  also a resource definition and defines only what flies are inside of the statement. 
<I>The first statement of the graph, with labeled parts</I>  The predicate, which addresses a property in the resource, is defined by the 
  tag <tt>&lt;types&gt;</tt> (of the <tt><a href=
<P>In this case, an RDF statement is extracted from the example, but no useful data is reached. Little can be done with an empty RDF container, and two more steps are needed to reach literals that contain names of the flies.    "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#</tt> 
<H4><A NAME="77069"></A> RDF containers</H4>  namespace).</p>
<P>Containers  <!--INDEX RDF (Resource Description Framework):containers -->  <!--INDEX containers:RDF --> are a list of resources or literals. They are a form of RDF  <!--INDEX resources:RDF:containers --> resource. There are three different container types: <TT>bag</TT>, <TT>sequence</TT>, and <TT>alternative</TT>. <TT>Bag</TT> is an unordered list of items, whereas <TT>sequence</TT> is an ordered list of items. They both allow duplicate values. <TT>Alternative</TT> is a list of values that could replace a particular property in a resource. <TT>Sequence</TT> is the most popular container for use in Mozilla applications because it frequently uses ordered lists of data. A container's graphical definition is an entire separate statement about its type and the items it contains. In <A HREF="#77012">Figure 10-6</A>, you can see the type of the container defined in the RDF statement with the property <TT>rdf:type</TT>. The remaining properties are the container's items.    
<P><CENTER><IMG SRC="foo.gif"></CENTER><p>The final part of the statement, the object, is the actual data of the predicate 
<P><I>Figure 10-6: <A NAME="77012"></A></I>  and a container of type bag. The container is an RDF resource that "holds", 
<I>The second statement of the graph, with labeled parts</I>  or points to, a collection of other resources. In the next section, container 
  types are discussed in depth. <a href="#77010">Figure 10-5</a> illustrates how 
<P>Once the container is defined, you can examine its collection of elements. At this point in the RDF code, direct comparisons can again be made from the code to the graph:  the triple originates from the root subject and includes the container object.</p>
<PRE>&lt;rdf:Bag&gt;    <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-5: <a name="77010"></a></i> <i>The first
     statement of the graph, with labeled parts</i></p>
     <p>In this case, an RDF statement is extracted from the
     example, but no useful data is reached. Little can be done with
     an empty RDF container, and two more steps are needed to reach
     literals that contain names of the flies.</p>
     <h4><a name="77069"></a> RDF containers</h4>
     <p>Containers 
     <!--INDEX RDF (Resource Description Framework):containers --> 
     <!--INDEX containers:RDF --> are a list of resources or
     literals. They are a form of RDF 
     <!--INDEX resources:RDF:containers --> resource. There are
     three different container types: <tt>bag</tt>,
     <tt>sequence</tt>, and <tt>alternative</tt>. <tt>Bag</tt> is an
     unordered list of items, whereas <tt>sequence</tt> is an
     ordered list of items. They both allow duplicate values.
     <tt>Alternative</tt> is a list of values that could replace a
     particular property in a resource. <tt>Sequence</tt> is the
     most popular container for use in Mozilla applications because
     it frequently uses ordered lists of data. A container's
     graphical definition is an entire separate statement about its
     type and the items it contains. In <a href="#77012">Figure
     10-6</a>, you can see the type of the container defined in the
     RDF statement with the property <tt>rdf:type</tt>. The
     remaining properties are the container's items.</p>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-6: <a name="77012"></a></i> <i>The second
     statement of the graph, with labeled parts</i></p>
     <p>Once the container is defined, you can examine its
     collection of elements. At this point in the RDF code, direct
     comparisons can again be made from the code to the graph:</p>
 <pre>
 &lt;rdf:Bag&gt;
 &lt;rdf:li&gt;  &lt;rdf:li&gt;
&lt;rdf:Description ...</PRE>&lt;rdf:Description ...
<P>Here, the <TT> <!--INDEX rdf\:li tag --> &lt;rdf:li&gt;</TT> tag is similar to the <TT>&lt;li&gt;</TT> tag in HTML, which stands for "list item." Moving from code to graph, the new representation is shown in <A HREF="#77012">Figure 10-6</A>.</pre>
<P>In <A HREF="#77012">Figure 10-6</A>, the subject is the instance of the container. This statement does not begin from <TT>rdf:Bag</TT> because that resource is only a type definition. The actual items in the container originate from the instance created in memory by any RDF processor, including Mozilla's.    <p>Here, the <tt><!--INDEX rdf\:li tag --> &lt;rdf:li&gt;</tt>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    tag is similar to the <tt>&lt;li&gt;</tt> tag in HTML, which
<P>Mozilla's RDF processor fills in the <TT>rdf:*(1)</TT> of the resource identifier in <A HREF="#77012">Figure 10-6</A> with a hashed value. The same is true for the container's resource identifier. The actual values come out as something like <TT>rdf:#$0mhkm1</TT>, though the values change each time the RDF document is loaded.<P></BLOCKQUOTE>    stands for "list item." Moving from code to graph, the new
<P>Objects inside of the container have <!--INDEX properties:RDF:containers -->  properties identified automatically as <TT>rdf:_1</TT>, <TT>rdf:_2</TT>, etc., as defined by the RDF model specification. However, RDF applications such as Mozilla may use different identifiers to differentiate list objects.    representation is shown in <a href="#77012">Figure
<H4><A NAME="77070"></A> Literals</H4>    10-6</a>.</p>
<P>The final  <!--INDEX RDF (Resource Description Framework):literals --> statement in <A HREF="#77026">Example 10-1</A> allows the predicate to reach the text data, the literal "horse" shown in <A HREF="#77014">Figure 10-7</A>. Note that the <TT>about</TT> reference on the <TT>Description</TT> is fictitious RDF, but it demonstrates the difference between a resource and a literal.    <p>In <a href="#77012">Figure 10-6</a>, the subject is the
<PRE>&lt;rdf:Description about="rdf:*(1)" fly:name="Horse"/&gt;</PRE>    instance of the container. This statement does not begin from
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <tt>rdf:Bag</tt> because that resource is only a type
<P><I>Figure 10-7: <A NAME="77014"></A></I>    definition. The actual items in the container originate from
<I>The third statement of the graph, with labeled parts</I>    the instance created in memory by any RDF processor, including
    Mozilla's.</p>
<P>The previous RDF  <!--INDEX RDF (Resource Description Framework):syntax:shorthand -->  <!--INDEX syntax, RDF:shorthand --> code for the literal is syntactic shorthand. Using this type of shortcut can make RDF much easier to read. The previous code snippet is the same as the longer and more cumbersome one shown here:    <blockquote>
<PRE>&lt;rdf:Description about="rdf:*(1)"&gt;      <div class="c21">
         NOTE
       </div>
       <p>Mozilla's RDF processor fills in the <tt>rdf:*(1)</tt> of
       the resource identifier in <a href="#77012">Figure 10-6</a>
       with a hashed value. The same is true for the container's
       resource identifier. The actual values come out as something
       like <tt>rdf:#$0mhkm1</tt>, though the values change each
       time the RDF document is loaded.</p>
     </blockquote>
     <p>Objects inside of the container have 
     <!--INDEX properties:RDF:containers --> properties identified
     automatically as <tt>rdf:_1</tt>, <tt>rdf:_2</tt>, etc., as
     defined by the RDF model specification. However, RDF
     applications such as Mozilla may use different identifiers to
     differentiate list objects.</p>
     <h4><a name="77070"></a> Literals</h4>
     <p>The final 
     <!--INDEX RDF (Resource Description Framework):literals -->
     statement in <a href="#77026">Example 10-1</a> allows the
     predicate to reach the text data, the literal "horse" shown in
     <a href="#77014">Figure 10-7</a>. Note that the <tt>about</tt>
     reference on the <tt>Description</tt> is fictitious RDF, but it
     demonstrates the difference between a resource and a
     literal.</p>
 <pre>
 &lt;rdf:Description about="rdf:*(1)" fly:name="Horse"/&gt;
 </pre>
     <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-7: <a name="77014"></a></i> <i>The third
     statement of the graph, with labeled parts</i></p>
     <p>The previous RDF 
     <!--INDEX RDF (Resource Description Framework):syntax:shorthand -->
     <!--INDEX syntax, RDF:shorthand --> code for the literal is
     syntactic shorthand. Using this type of shortcut can make RDF
     much easier to read. The previous code snippet is the same as
     the longer and more cumbersome one shown here:</p>
 <pre>
 &lt;rdf:Description about="rdf:*(1)"&gt;
 &lt;fly:name&gt;Horse&lt;/fly:name&gt;  &lt;fly:name&gt;Horse&lt;/fly:name&gt;
&lt;/rdf:Description&gt;</PRE>&lt;/rdf:Description&gt;
<P>The shorthand version of this statement can be useful when you have a lot of data or when you want to use one syntax to show all relationships in the graph.</pre>
<H4><A NAME="77071"></A> The RDF syntax and RDF graphs</H4>    <p>The shorthand version of this statement can be useful when
<P><A HREF="#77016">Figure 10-8</A> shows the entire RDF graph for the RDF file in <A HREF="#77026">Example 10-1</A>. This graph was compiled by combining the concepts you've seen in Figures 10-5 through 10-7.    you have a lot of data or when you want to use one syntax to
<P>As you can see, the statements fit together quite nicely. Four resources originate from the container, and one is the container type definition. The other two properties are numbered according to their order in the RDF file.    show all relationships in the graph.</p>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <h4><a name="77071"></a> The RDF syntax and RDF graphs</h4>
<P><I>Figure 10-8: <A NAME="77016"></A></I>    <p><a href="#77016">Figure 10-8</a> shows the entire RDF graph
<I>The full graph</I>    for the RDF file in <a href="#77026">Example 10-1</a>. This
    graph was compiled by combining the concepts you've seen in
<H3><A NAME="77072"></A> Building an RDF File from Scratch</H3>    Figures 10-5 through 10-7.</p>
<P>Now that  <!--INDEX RDF (Resource Description Framework):files:creating -->  <!--INDEX files:RDF:creating --> you understand the basic principles of a simple RDF file, this section steps through the creation of an RDF file from information found in regular text:    <p>As you can see, the statements fit together quite nicely.
<BLOCKQUOTE>There is a jar with the name urn:root. Inside of it there are two types of flies listed as House and Horse.    Four resources originate from the container, and one is the
There are three Horse flies. The Face Fly, coded in green, is officially identified as "musca autumnalis". The Stable Fly, coded in black, has the identification "stomoxys_calcitrans." The red-coded Horn Fly, located in Kansas, is identified as "haematobia_irritans."    container type definition. The other two properties are
There are also three house flies. "musca_domestica," coded in brown, has the name "Common House Fly." A gray fly named "Carrion Fly" has the ID "sarcophagid" and is found globally. Finally, The "Office Fly," coded with white, is prevalent in the Bay Area.</BLOCKQUOTE>    numbered according to their order in the RDF file.</p>
<P>You can use the techniques described here to model the data you want in your application: spreadsheet-like rosters of people, family trees, or catalogs of books or other items.    <div class="c22">
<H4><A NAME="77073"></A> Identify namespaces</H4>      <img src="foo.gif">
<P>The new  <!--INDEX namespaces:identifying, creating RDF files -->  <!--INDEX RDF (Resource Description Framework):files:identifying namespaces -->  <!--INDEX files:RDF:identifying namespaces --> RDF file will have three namespaces including the RDF namespace. The result is two different data types that are connected in an RDF graph. For the sake of the example, one namespace is not in the standard URL format. Here is how the RDF file namespaces are set up:    </div>
<PRE>&lt;?xml version="1.0"?&gt;    <p><i>Figure 10-8: <a name="77016"></a></i> <i>The full
&lt;rdf:RDF xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    graph</i></p>
xmlns:fly="<A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#"    <h3><a name="77072"></a> Building an RDF File from Scratch</h3>
     <p>Now that 
     <!--INDEX RDF (Resource Description Framework):files:creating -->
     <!--INDEX files:RDF:creating --> you understand the basic
     principles of a simple RDF file, this section steps through the
     creation of an RDF file from information found in regular
     text:</p>
     <blockquote>
       There is a jar with the name urn:root. Inside of it there are
       two types of flies listed as House and Horse. There are three
       Horse flies. The Face Fly, coded in green, is officially
       identified as "musca autumnalis". The Stable Fly, coded in
       black, has the identification "stomoxys_calcitrans." The
       red-coded Horn Fly, located in Kansas, is identified as
       "haematobia_irritans." There are also three house flies.
       "musca_domestica," coded in brown, has the name "Common House
       Fly." A gray fly named "Carrion Fly" has the ID "sarcophagid"
       and is found globally. Finally, The "Office Fly," coded with
       white, is prevalent in the Bay Area.
     </blockquote>
     <p>You can use the techniques described here to model the data
     you want in your application: spreadsheet-like rosters of
     people, family trees, or catalogs of books or other items.</p>
     <h4><a name="77073"></a> Identify namespaces</h4>
     <p>The new 
     <!--INDEX namespaces:identifying, creating RDF files --> 
     <!--INDEX RDF (Resource Description Framework):files:identifying namespaces -->
     <!--INDEX files:RDF:identifying namespaces --> RDF file will
     have three namespaces including the RDF namespace. The result
     is two different data types that are connected in an RDF graph.
     For the sake of the example, one namespace is not in the
     standard URL format. Here is how the RDF file namespaces are
     set up:</p>
 <pre>
 &lt;?xml version="1.0"?&gt;
 &lt;rdf:RDF xmlns:rdf="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
 xmlns:fly="<a href=
 "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
 xmlns:location="fly-location#"&gt;  xmlns:location="fly-location#"&gt;
&lt;/rdf:RDF&gt;</PRE>&lt;/rdf:RDF&gt;
<H4><A NAME="77074"></A> Root resource</H4></pre>
<P>This file's  <!--INDEX resources:RDF:creating files -->  <!--INDEX root resources, RDF files -->  <!--INDEX RDF (Resource Description Framework):files:root resources -->  <!--INDEX files:RDF:root resources --> root resource is an <TT>urn:root</TT>, which is the conventional name for root nodes in Mozilla's RDF files. When rendering RDF files, defining a root node for processing the document can be useful-especially when building templates. This root node can be entered as the first item in the file:    <h4><a name="77074"></a> Root resource</h4>
<PRE>&lt;?xml version="1.0"?&gt;    <p>This file's <!--INDEX resources:RDF:creating files --> 
&lt;rdf:RDF xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    <!--INDEX root resources, RDF files --> 
xmlns:fly="<A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#"    <!--INDEX RDF (Resource Description Framework):files:root resources -->
     <!--INDEX files:RDF:root resources --> root resource is an
     <tt>urn:root</tt>, which is the conventional name for root
     nodes in Mozilla's RDF files. When rendering RDF files,
     defining a root node for processing the document can be
     useful-especially when building templates. This root node can
     be entered as the first item in the file:</p>
 <pre>
 &lt;?xml version="1.0"?&gt;
 &lt;rdf:RDF xmlns:rdf="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
 xmlns:fly="<a href=
 "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
 xmlns:location="fly-location#"&gt;  xmlns:location="fly-location#"&gt;
 &lt;rdf:Description about="urn:root"&gt;  &lt;rdf:Description about="urn:root"&gt;
 &lt;/rdf:Description&gt;  &lt;/rdf:Description&gt;
&lt;/rdf:RDF&gt;</PRE>&lt;/rdf:RDF&gt;
<H4><A NAME="77075"></A> Root sequence</H4></pre>
<P>Next, a  <!--INDEX sequences, RDF:creating files -->  <!--INDEX root sequences, RDF files -->  <!--INDEX RDF (Resource Description Framework):files:root sequesces -->  <!--INDEX files:RDF:root sequesces --> generic tag needs to be used to specify a sequence of "fly" data. As in <A HREF="#77028">Example 10-2</A>, <TT>&lt;fly:list&gt;</TT> is used as a list of fly types. This tag is a generic name because of the way XUL templates process lists of RDF data. If a list of data has sublists, as in the following examples, then they must use the same tag name to recurse correctly for the data they contain.    <h4><a name="77075"></a> Root sequence</h4>
<P><A HREF="#77028">Example 10-2</A> represents all the information given in the first paragraph of the text example: "There is a jar set up with the name <I>urn:root</I>. Inside of it there are two types of flies, listed as House and Horse."    <p>Next, a <!--INDEX sequences, RDF:creating files --> 
    <!--INDEX root sequences, RDF files --> 
<P><I>Example 10-2: <A NAME="77028"></A></I>    <!--INDEX RDF (Resource Description Framework):files:root sequesces -->
<I>RDF root sequence</I>    <!--INDEX files:RDF:root sequesces --> generic tag needs to be
<PRE> &lt;?xml version="1.0"?&gt;    used to specify a sequence of "fly" data. As in <a href=
 &lt;rdf:RDF xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    "#77028">Example 10-2</a>, <tt>&lt;fly:list&gt;</tt> is used as
          xmlns:fly="<A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#"    a list of fly types. This tag is a generic name because of the
     way XUL templates process lists of RDF data. If a list of data
     has sublists, as in the following examples, then they must use
     the same tag name to recurse correctly for the data they
     contain.</p>
     <p><a href="#77028">Example 10-2</a> represents all the
     information given in the first paragraph of the text example:
     "There is a jar set up with the name <i>urn:root</i>. Inside of
     it there are two types of flies, listed as House and
     Horse."</p>
     <p><i>Example 10-2: <a name="77028"></a></i> <i>RDF root
     sequence</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;rdf:RDF xmlns:rdf="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
           xmlns:fly="<a href=
 "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
           xmlns:location="fly-location#"&gt;            xmlns:location="fly-location#"&gt;
    &lt;rdf:Description about="urn:root"&gt;     &lt;rdf:Description about="urn:root"&gt;
      &lt;fly:list&gt;       &lt;fly:list&gt;
Line 188  xmlns:location="fly-location#"&gt; Line 566  xmlns:location="fly-location#"&gt;
        &lt;/rdf:Seq&gt;         &lt;/rdf:Seq&gt;
      &lt;/fly:list&gt;       &lt;/fly:list&gt;
    &lt;/rdf:Description&gt;     &lt;/rdf:Description&gt;
 &lt;/rdf:RDF&gt;</PRE> &lt;/rdf:RDF&gt;
</pre>
<P>An RDF sequence resides with its list of resources inside <TT>&lt;fly:list&gt;</TT>. Here, shorthand RDF specifies a label with the <TT>fly:label</TT> attribute. The <TT>ID</TT> attribute within this sequence is actually a pointer to the main definition of the resource described by an <TT>about</TT> attribute of the same value. The <TT>about</TT> attribute includes a <TT>#</TT> in its identifier, much like HTML anchors use <TT>&lt;a href="#frag"&gt;</TT> to refer to <TT>&lt;a name="frag"&gt;</TT>. For example, <TT>ID="Horse"</TT> points to <TT>about="#Horse</TT>" elsewhere in the file, allowing you to add to the description of any element with new properties and resources.    <p>An RDF sequence resides with its list of resources inside
<H4><A NAME="77076"></A> Secondary sequences and literals</H4>    <tt>&lt;fly:list&gt;</tt>. Here, shorthand RDF specifies a
<P>The  <!--INDEX sequences, RDF:creating files -->  <!--INDEX secondary sequences, RDF files -->  <!--INDEX RDF (Resource Description Framework):files:secondary sequesces -->  <!--INDEX files:RDF:secondary sequesces --> <TT>Horse</TT> and <TT>House</TT> resources need to be defined next. <A HREF="#77030">Example 10-3</A> shows the creation of <TT>Horse</TT> from the second paragraph. The process for creating <TT>House</TT> is almost identical.    label with the <tt>fly:label</tt> attribute. The <tt>ID</tt>
    attribute within this sequence is actually a pointer to the
<P><I>Example 10-3: <A NAME="77030"></A></I>    main definition of the resource described by an <tt>about</tt>
<I>The Horse sequence</I>    attribute of the same value. The <tt>about</tt> attribute
<PRE> &lt;rdf:Description about="#Horse"&gt;    includes a <tt>#</tt> in its identifier, much like HTML anchors
     use <tt>&lt;a href="#frag"&gt;</tt> to refer to <tt>&lt;a
     name="frag"&gt;</tt>. For example, <tt>ID="Horse"</tt> points
     to <tt>about="#Horse</tt>" elsewhere in the file, allowing you
     to add to the description of any element with new properties
     and resources.</p>
     <h4><a name="77076"></a> Secondary sequences and literals</h4>
     <p>The <!--INDEX sequences, RDF:creating files --> 
     <!--INDEX secondary sequences, RDF files --> 
     <!--INDEX RDF (Resource Description Framework):files:secondary sequesces -->
     <!--INDEX files:RDF:secondary sequesces --> <tt>Horse</tt> and
     <tt>House</tt> resources need to be defined next. <a href=
     "#77030">Example 10-3</a> shows the creation of <tt>Horse</tt>
     from the second paragraph. The process for creating
     <tt>House</tt> is almost identical.</p>
     <p><i>Example 10-3: <a name="77030"></a></i> <i>The Horse
     sequence</i></p>
 <pre>
  &lt;rdf:Description about="#Horse"&gt;
      &lt;fly:list&gt;       &lt;fly:list&gt;
        &lt;rdf:Seq&gt;         &lt;rdf:Seq&gt;
          &lt;rdf:li&gt;           &lt;rdf:li&gt;
Line 217  xmlns:location="fly-location#"&gt; Line 613  xmlns:location="fly-location#"&gt;
          &lt;/rdf:li&gt;           &lt;/rdf:li&gt;
        &lt;/rdf:Seq&gt;         &lt;/rdf:Seq&gt;
      &lt;/fly:list&gt;       &lt;/fly:list&gt;
   &lt;/rdf:Description&gt;</PRE>   &lt;/rdf:Description&gt;
</pre>
<P>Here the shorthand RDF definition continues to use only the attributes. Again, a <TT>&lt;fly:list&gt;</TT> is defined and the items inside it are listed. The listed values have multiple attribute values, all of which are RDF literals. In longhand with RDF showing all literals, the last item would be written out as follows:    <p>Here the shorthand RDF definition continues to use only the
<PRE>&lt;rdf:li&gt;    attributes. Again, a <tt>&lt;fly:list&gt;</tt> is defined and
     the items inside it are listed. The listed values have multiple
     attribute values, all of which are RDF literals. In longhand
     with RDF showing all literals, the last item would be written
     out as follows:</p>
 <pre>
 &lt;rdf:li&gt;
 &lt;rdf:Description about="haematobia_irritans "&gt;  &lt;rdf:Description about="haematobia_irritans "&gt;
 &lt;fly:label&gt;Horn Fly&lt;/fly:label&gt;  &lt;fly:label&gt;Horn Fly&lt;/fly:label&gt;
 &lt;fly:color&gt;red&lt;/fly:color&gt;  &lt;fly:color&gt;red&lt;/fly:color&gt;
 &lt;location:location&gt;Kansas&lt;/location:location&gt;  &lt;location:location&gt;Kansas&lt;/location:location&gt;
 &lt;/rdf:Description&gt;  &lt;/rdf:Description&gt;
&lt;/rdf:li&gt;</PRE>&lt;/rdf:li&gt;
<P>The two different namespace literals are both resource attributes. <TT>haematobia_irritans</TT> is used as the resource identifier because it is a unique value among all data.</pre>
<P>Laying out the data in the same pattern gives you the final, full RDF file in <A HREF="#77032">Example 10-4</A>.    <p>The two different namespace literals are both resource
    attributes. <tt>haematobia_irritans</tt> is used as the
<P><I>Example 10-4: <A NAME="77032"></A></I>    resource identifier because it is a unique value among all
<I>Entire RDF file</I>    data.</p>
<PRE> &lt;?xml version="1.0"?&gt;    <p>Laying out the data in the same pattern gives you the final,
 &lt;rdf:RDF xmlns:rdf="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    full RDF file in <a href="#77032">Example 10-4</a>.</p>
          xmlns:fly="<A HREF="http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</A>#"    <p><i>Example 10-4: <a name="77032"></a></i> <i>Entire RDF
     file</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;rdf:RDF xmlns:rdf="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
           xmlns:fly="<a href=
 "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
           xmlns:location="fly-location#"&gt;            xmlns:location="fly-location#"&gt;
    &lt;rdf:Description about="urn:root"&gt;     &lt;rdf:Description about="urn:root"&gt;
      &lt;fly:list&gt;       &lt;fly:list&gt;
Line 293  xmlns:location="fly-location#"&gt; Line 702  xmlns:location="fly-location#"&gt;
        &lt;/rdf:Seq&gt;         &lt;/rdf:Seq&gt;
      &lt;/fly:list&gt;       &lt;/fly:list&gt;
    &lt;/rdf:Description&gt;     &lt;/rdf:Description&gt;
 &lt;/rdf:RDF&gt;</PRE> &lt;/rdf:RDF&gt;
</pre>
<P><A HREF="#77032">Example 10-4</A> shows the RDF data used in several template examples in <A HREF="ch09.html#77034">Chapter 9</A>. <    <p><a href="#77032">Example 10-4</a> shows the RDF data used in
HREF="ch09.html#77022">Example 9-4</A> includes the <I>10-4.rdf</I> datasource, as do many of those templates. You can copy the data out of <    several template examples in <a href="ch09.html#77034">Chapter
HREF="#77032">Example 10-4</A> and into a file of the same name to use as a datasource.    9</a>. <a href="ch09.html#77022">Example 9-4</a> includes the
<H2><A NAME="77077"></A> The Mozilla Content Model</H2>    <i>10-4.rdf</i> datasource, as do many of those templates. You
<P>One theme  <!--INDEX content model:overview -->  <!--INDEX Gecko rendering engine:Mozilla content model --> of this book-and a general goal of the Mozilla development environment-is that developers can create real applications using many of the same technologies they use to create a web page. The Gecko rendering engine, sitting at the heart of Mozilla and happily rendering web content, XML files, XUL interfaces, and whatever else they can support, is what makes this type of development possible. But how does Gecko know what to render and how? How can RDF data be handed over so that Gecko knows how to draw it?    can copy the data out of <a href="#77032">Example 10-4</a> and
<P>When a browser uses the same engine to draw everything-its own interface as well as the various kinds of content it supports-that engine treats everything as content. Gecko needs a way to understand all the various parts of the Mozilla browser itself-such as the sidebar, the toolbars, and the mail folders and mail messages-as resources it can render and display in the Mozilla chrome. This approach to the Mozilla application interface is called the content model.    into a file of the same name to use as a datasource.</p>
<P>In Mozilla's content model, XUL documents and other interface resources are transformed into RDF when they are read. Each chunk of content is represented as a separate RDF datasource (see the next section, <A HREF="#77078">"Datasources</A>," for more information) and is then fed to the XUL Content Builder and rendered as the actual bits on the screen, as <A HREF="#77018">Figure 10-9</A> shows.    <h2><a name="77077"></a> The Mozilla Content Model</h2>
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <p>One theme <!--INDEX content model:overview --> 
<P><I>Figure 10-9: <A NAME="77018"></A></I>    <!--INDEX Gecko rendering engine:Mozilla content model --> of
<I>Diagram of Mozilla's content model</I>    this book-and a general goal of the Mozilla development
    environment-is that developers can create real applications
<P>As you can see in <A HREF="#77018">Figure 10-9</A>, the content model can be complex. The XUL documents in <A HREF="#77018">Figure 10-9</A> are files such as <I>navigator.xul</I>, which defines the main browser window's basic layout; the RDF documents include files like <I>help-toc.rdf</I>, which defines the Mozilla Help viewer's table of contents. The list of mail folders and accounts shown in <A HREF="#77034">Example 10-5</A> are part of the built-in data that Mozilla renders into browser content.    using many of the same technologies they use to create a web
<P>Whatever the source, the content model gets everything processed in-memory as RDF so that any data can be combined and formatted into XUL or other interface code. All sources of RDF data are called datasources.    page. The Gecko rendering engine, sitting at the heart of
<H3><A NAME="77078"></A> Datasources</H3>    Mozilla and happily rendering web content, XML files, XUL
<P>A datasource  <!--INDEX content model:datasources -->  <!--INDEX datasources:content model --> is a collection of related, typically homogenous, RDF statements. A datasource may be a single RDF file like <I>localstore.rdf</I>, a combination of files, or RDF structures that exist only in memory (as discussed later).    interfaces, and whatever else they can support, is what makes
<P>In Mozilla, datasources represent the messages in your email inbox, your bookmarks, the packages you installed, your browser history, and other sets of data. Datasources can be combined easily (or "composed," which is where the term "composite datasource" comes from).    this type of development possible. But how does Gecko know what
<H4><A NAME="77079"></A> A datasource example: mailboxes</H4>    to render and how? How can RDF data be handed over so that
<P>Several  <!--INDEX content model:datasources:example -->  <!--INDEX datasources:content model:example --> datasources describe all the folders and messages in Mozilla's email. A root datasource called <TT>msgaccounts</TT> describes which mail servers and accounts are present. Separate datasources then represent each account separately. These datasources are composed to create the entire email storage system. The higher levels of this content structure look like <A HREF="#77034">Example 10-5</A>.    Gecko knows how to draw it?</p>
    <p>When a browser uses the same engine to draw everything-its
<P><I>Example 10-5: <A NAME="77034"></A></I>    own interface as well as the various kinds of content it
<I>Content model of email datasources</I>    supports-that engine treats everything as content. Gecko needs
<PRE> msgaccounts:/    a way to understand all the various parts of the Mozilla
 +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#child</TD> --&gt;    browser itself-such as the sidebar, the toolbars, and the mail
     imap:</TD><TT><I>//<A HREF="MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</A></I></TT>    folders and mail messages-as resources it can render and
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#IsServer</TD> --&gt; "true"    display in the Mozilla chrome. This approach to the Mozilla
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#child</TD> --&gt;    application interface is called the content model.</p>
     |        imap:</TD><TT><I>//<A HREF="MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</A></I></TT>    <p>In Mozilla's content model, XUL documents and other
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#TotalMessages</TD> --&gt; "4"    interface resources are transformed into RDF when they are
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#IsServer</TD> --&gt; "false"    read. Each chunk of content is represented as a separate RDF
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#MessageChild</TD> --&gt;    datasource (see the next section, <a href=
     |        imap_message://<A HREF="MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</A>#1    "#77078">"Datasources</a>," for more information) and is then
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#MessageChild</TD> --&gt;    fed to the XUL Content Builder and rendered as the actual bits
     |        imap_message://<A HREF="MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</A>#2    on the screen, as <a href="#77018">Figure 10-9</a> shows.</p>
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#MessageChild</TD> --&gt;    <div class="c22">
       <img src="foo.gif">
     </div>
     <p><i>Figure 10-9: <a name="77018"></a></i> <i>Diagram of
     Mozilla's content model</i></p>
     <p>As you can see in <a href="#77018">Figure 10-9</a>, the
     content model can be complex. The XUL documents in <a href=
     "#77018">Figure 10-9</a> are files such as
     <i>navigator.xul</i>, which defines the main browser window's
     basic layout; the RDF documents include files like
     <i>help-toc.rdf</i>, which defines the Mozilla Help viewer's
     table of contents. The list of mail folders and accounts shown
     in <a href="#77034">Example 10-5</a> are part of the built-in
     data that Mozilla renders into browser content.</p>
     <p>Whatever the source, the content model gets everything
     processed in-memory as RDF so that any data can be combined and
     formatted into XUL or other interface code. All sources of RDF
     data are called datasources.</p>
     <h3><a name="77078"></a> Datasources</h3>
     <p>A datasource <!--INDEX content model:datasources --> 
     <!--INDEX datasources:content model --> is a collection of
     related, typically homogenous, RDF statements. A datasource may
     be a single RDF file like <i>localstore.rdf</i>, a combination
     of files, or RDF structures that exist only in memory (as
     discussed later).</p>
     <p>In Mozilla, datasources represent the messages in your email
     inbox, your bookmarks, the packages you installed, your browser
     history, and other sets of data. Datasources can be combined
     easily (or "composed," which is where the term "composite
     datasource" comes from).</p>
     <h4><a name="77079"></a> A datasource example: mailboxes</h4>
     <p>Several <!--INDEX content model:datasources:example --> 
     <!--INDEX datasources:content model:example --> datasources
     describe all the folders and messages in Mozilla's email. A
     root datasource called <tt>msgaccounts</tt> describes which
     mail servers and accounts are present. Separate datasources
     then represent each account separately. These datasources are
     composed to create the entire email storage system. The higher
     levels of this content structure look like <a href=
     "#77034">Example 10-5</a>.</p>
     <p><i>Example 10-5: <a name="77034"></a></i> <i>Content model
     of email datasources</i></p>
 <pre>
  msgaccounts:/
  +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
      imap:&lt;/td&gt;<tt><i>//<a href=
 "MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</a></i></tt>
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "true"
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
      |        imap:&lt;/td&gt;<tt><i>//<a href=
 "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a></i></tt>
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#TotalMessages&lt;/td&gt; --&gt; "4"
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "false"
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
      |        imap_message://<a href=
 "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a>#1
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
      |        imap_message://<a href=
 "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a>#2
      |    +-- <a href=
 "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
      |    etc...       |    etc...
      |       |
 +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#child</TD> --&gt; +-- <a href=
     mailbox:</TD><TT><I>//<A HREF="MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</A></I></TT>"http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#IsServer</TD> --&gt; "true"     mailbox:&lt;/td&gt;<tt><i>//<a href=
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#child</TD> --&gt;"MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</a></i></tt>
     |        mailbox:</TD><TT><I>//<A HREF="MAILTO:oeschger@pop.oeschger.com/INBOX">oeschger@pop.oeschger.com/INBOX</A></I></TT>     |    +-- <a href=
     |    +-- <A HREF="http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</A>#TotalMessages</TD> --&gt; "2""http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "true"
     |    etc...</PRE>     |    +-- <a href=
"http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
<P>Each direct child of the root <I>msgaccounts:/</I> is a mail server. This portion of the graph shows two Mozilla email accounts that are the primary children: <I>imap://<A HREF="MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</A></I> and <I>mailbox://<A HREF="MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</A></I>. These two accounts are entirely different datasources that can exist on their own. The content model for email actually extends much lower than what is represented in this outline. It uses RDF to represent the data all the way into the actual message lists.     |        mailbox:&lt;/td&gt;<tt><i>//<a href=
<H4><A NAME="77080"></A> Types of datasources</H4>"MAILTO:oeschger@pop.oeschger.com/INBOX">oeschger@pop.oeschger.com/INBOX</a></i></tt>
<P>As you  <!--INDEX content model:datasources:types -->  <!--INDEX datasources:content model:types --> may have already inferred, email accounts are not actually RDF files. Mozilla provides a custom RDF map of all email accounts and messages and the content model represents the accounts and their relationships to one another as RDF so they can be integrated and rendered properly. The interface to this custom mail RDF map makes it possible to display a list of messages and mailboxes in a <TT>&lt;tree&gt;</TT> template.     |    +-- <a href=
<P>Another example of a datasource, the <I>in-memory-datasource,</I> doesn't come from an actual RDF file. When an in-memory datasource is created, it doesn't contain data. However, data can be inserted into it and stored in memory until the datasource is destroyed. In-memory datasources frequently represent ephemeral data like search results. Other basic datasource types are described in <A HREF="#77022">Table 10-2</A>."http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#TotalMessages&lt;/td&gt; --&gt; "2"
     |    etc...
<P><I>Table 10-2: <A NAME="77022"></A></I></pre>
<I>Types of datasources</I>    <p>Each direct child of the root <i>msgaccounts:/</i> is a mail
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Type</B></TD> <TD><B>  Description</B></TD></TR>    server. This portion of the graph shows two Mozilla email
<TR><TD>  Local datasource</TD>     <TD>  A local datasource is an RDF graph contained in an RDF/XML file on a local disk. All RDF files in the chrome registry (e.g., </TD><I>all-packages.rdf</I> in the <I>chrome</I> directory, which keeps track packages installed in Mozilla) are local datasources.</TR>    accounts that are the primary children: <i>imap://<a href=
<TR><TD>  Remote datasource</TD>     <TD>  RDF can be accessed locally or remotely. A remote datasource is an RDF/XML file stored on a server and accessed with a URL.</TD></TR>    "MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</a></i>
<TR><TD>  In-memory datasource</TD>     <TD>  An in-memory datasource exists only in memory during a Mozilla session. In-memory datasources are built with </TD><I>assertions</I>, statements that build an in-memory data model by adding resources, properties, and value to those.</TR>    and <i>mailbox://<a href=
<TR><TD>  Built-in datasource</TD>     <TD>  These unique, prefabricated datasources represent something used often in Mozilla, such as a built-in </TD><I>filesystem</I> datasource and a <I>history</I> datasource.</TR>    "MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</a></i>.
<TR><TD>  Composite datasource</TD>     <TD>  A composite datasource may be a combination of any of the datasources previously listed. RDF allows you to merge different graphs.</TD></TR></TABLE><P>    These two accounts are entirely different datasources that can
    exist on their own. The content model for email actually
<H2><A NAME="77081"></A> RDF Components and Interfaces</H2>    extends much lower than what is represented in this outline. It
<P>Once you are comfortable using XUL templates to display RDF data (see <A HREF="ch09.html#77034">Chapter 9</A>), you should explore the various     uses RDF to represent the data all the way into the actual
ways to create and change that data. In Mozilla, data is generally RDF, since all data in Mozilla is either represented formally in RDF or passed through the RDF-based content model for display. Use the tools described in this section to manipulate RDF and the data it represents.    message lists.</p>
<P>Mozilla has a great set of interfaces for creating, manipulating, and managing RDF, and it also provides ready-made RDF components that represent datasources used in Mozilla. Think of RDF interfaces as ways to manipulate RDF directly and of RDF components as sets of the interfaces already associated with a particular kind of data, such as bookmarks. Interfaces tend to deal with the RDF model itself, without regard to the kinds of data being handled, while RDF components give you control over specific Mozilla data. See the next two sections for more information on RDF interfaces and components.    <h4><a name="77080"></a> Types of datasources</h4>
<H3><A NAME="77082"></A> What Is an RDF Component?</H3>    <p>As you <!--INDEX content model:datasources:types --> 
<P>An RDF  <!--INDEX RDF (Resource Description Framework):components, overview -->  <!--INDEX components:RDF, overview --> component may implement any number of the general RDF interfaces described here, in addition to special interfaces for accessing and controlling the data the datasource represents. For example, <TT>@mozilla.org/rdf/data-source;1?name=internetsearch</TT> is an RDF component used to control Mozilla's internet searching facility. In Mozilla, a component can act as a library of code specific to a given set of data or domain. The <TT> <!--INDEX internetsearch component --> internetsearch</TT> component is instantiated and used to recall text entered in a previous search:    <!--INDEX datasources:content model:types --> may have already
<PRE>var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]    inferred, email accounts are not actually RDF files. Mozilla
     provides a custom RDF map of all email accounts and messages
     and the content model represents the accounts and their
     relationships to one another as RDF so they can be integrated
     and rendered properly. The interface to this custom mail RDF
     map makes it possible to display a list of messages and
     mailboxes in a <tt>&lt;tree&gt;</tt> template.</p>
     <p>Another example of a datasource, the
     <i>in-memory-datasource,</i> doesn't come from an actual RDF
     file. When an in-memory datasource is created, it doesn't
     contain data. However, data can be inserted into it and stored
     in memory until the datasource is destroyed. In-memory
     datasources frequently represent ephemeral data like search
     results. Other basic datasource types are described in <a href=
     "#77022">Table 10-2</a>.</p>
     <p><i>Table 10-2: <a name="77022"></a></i> <i>Types of
     datasources</i></p>
     <i>all-packages.rdf</i>in the <i>chrome</i>directory, which
     keeps track packages installed in Mozilla) are local
     datasources.<i>assertions</i>, statements that build an
     in-memory data model by adding resources, properties, and value
     to those.<i>filesystem</i>datasource and a
     <i>history</i>datasource.
     <table width="100%" border="1">
       <tr>
         <td><b>Type</b></td>
         <td><b>Description</b></td>
       </tr>
       <tr>
         <td>Local datasource</td>
         
     <td>A local datasource is an RDF graph contained in an RDF/XML file on a local 
       disk. All RDF files in the chrome directory (e.g., <i>all-packages.rdf</i> 
       in the <i>chrome</i> directory, which keeps track of packages installed 
       in Mozilla) are local datasources.</td>
       </tr>
       <tr>
         <td>Remote datasource</td>
         <td>RDF can be accessed locally or remotely. A remote
         datasource is an RDF/XML file stored on a server and
         accessed with a URL.</td>
       </tr>
       <tr>
         <td>In-memory datasource</td>
         
     <td>An in-memory datasource exists only in memory during a Mozilla session. 
       In-memory datasources are built with <i>assertions</i>, statements that 
       build an in-memory data model by adding resources, add properties, and value 
       those.</td>
       </tr>
       <tr>
         <td>Built-in datasource</td>
         
     <td>These unique, prefabricated datasources represent something used often 
       in Mozilla, such as a built-in <i>filesystem</i> datasource and a <i>history</i> 
       datasource.</td>
       </tr>
       <tr>
         <td>Composite datasource</td>
         <td>A composite datasource may be a combination of any of
         the datasources previously listed. RDF allows you to merge
         different graphs.</td>
       </tr>
     </table>
     <h2><a name="77081"></a> RDF Components and Interfaces</h2>
     <p>Once you are comfortable using XUL templates to display RDF
     data (see <a href="ch09.html#77034">Chapter 9</a>), you should
     explore the various ways to create and change that data. In
     Mozilla, data is generally RDF, since all data in Mozilla is
     either represented formally in RDF or passed through the
     RDF-based content model for display. Use the tools described in
     this section to manipulate RDF and the data it represents.</p>
     <p>Mozilla has a great set of interfaces for creating,
     manipulating, and managing RDF, and it also provides ready-made
     RDF components that represent datasources used in Mozilla.
     Think of RDF interfaces as ways to manipulate RDF directly and
     of RDF components as sets of the interfaces already associated
     with a particular kind of data, such as bookmarks. Interfaces
     tend to deal with the RDF model itself, without regard to the
     kinds of data being handled, while RDF components give you
     control over specific Mozilla data. See the next two sections
     for more information on RDF interfaces and components.</p>
     <h3><a name="77082"></a> What Is an RDF Component?</h3>
     <p>An RDF 
     <!--INDEX RDF (Resource Description Framework):components, overview -->
     <!--INDEX components:RDF, overview --> component may implement
     any number of the general RDF interfaces described here, in
     addition to special interfaces for accessing and controlling
     the data the datasource represents. For example,
     <tt>@mozilla.org/rdf/data-source;1?name=internetsearch</tt> is
     an RDF component used to control Mozilla's internet searching
     facility. In Mozilla, a component can act as a library of code
     specific to a given set of data or domain. The <tt>
     <!--INDEX internetsearch component --> internetsearch</tt>
     component is instantiated and used to recall text entered in a
     previous search:</p>
 <pre>
 var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
 .getService(Components.interfaces.nsIInternetSearchService);  .getService(Components.interfaces.nsIInternetSearchService);
searchDS.RememberLastSearchText(escapedSearchStr);
searchDS.RememberLastSearchText(escapedSearchStr);</PRE></pre>
<P>This RDF component implements an interface called <I> <!--INDEX nsIInternetSearchService interface -->  <!--INDEX interfaces:nsIInternetSearchService --> nsIInternetSearchService</I>, which is selected from the component and used to call the <TT>RememberLastSearchText</TT> method. Although you can also use the <TT>getService</TT> method to get one of a component's RDF interfaces (e.g., by using <TT>getService(Components.interfaces.nsIRDFDataSource)</TT>), doing so is seldom necessary in practice. RDF components are tailored to the datasources they represent and usually provide all the access you need to access that data directly. <A HREF="#77036">Example 10-6</A> lists RDF components in Mozilla.    <p>This RDF component implements an interface called <i>
    <!--INDEX nsIInternetSearchService interface --> 
<P><I>Example 10-6: <A NAME="77036"></A></I>    <!--INDEX interfaces:nsIInternetSearchService -->
<I>RDF-specific components built into Mozilla</I>    nsIInternetSearchService</i>, which is selected from the
<PRE> @mozilla.org/rdf/container;1    component and used to call the <tt>RememberLastSearchText</tt>
     method. Although you can also use the <tt>getService</tt>
     method to get one of a component's RDF interfaces (e.g., by
     using
     <tt>getService(Components.interfaces.nsIRDFDataSource)</tt>),
     doing so is seldom necessary in practice. RDF components are
     tailored to the datasources they represent and usually provide
     all the access you need to access that data directly. <a href=
     "#77036">Example 10-6</a> lists RDF components in Mozilla.</p>
     <p><i>Example 10-6: <a name="77036"></a></i> <i>RDF-specific
     components built into Mozilla</i></p>
 <pre>
  @mozilla.org/rdf/container;1
  @mozilla.org/rdf/content-sink;1   @mozilla.org/rdf/content-sink;1
  @mozilla.org/rdf/datasource;1?name=addresscard   @mozilla.org/rdf/datasource;1?name=addresscard
  @mozilla.org/rdf/datasource;1?name=addressdirectory   @mozilla.org/rdf/datasource;1?name=addressdirectory
Line 403  searchDS.RememberLastSearchText(escapedS Line 988  searchDS.RememberLastSearchText(escapedS
  @mozilla.org/rdf/resource-factory;1?name=mailbox   @mozilla.org/rdf/resource-factory;1?name=mailbox
  @mozilla.org/rdf/resource-factory;1?name=news   @mozilla.org/rdf/resource-factory;1?name=news
  @mozilla.org/rdf/xml-parser;1   @mozilla.org/rdf/xml-parser;1
 @mozilla.org/rdf/xml-serializer;1</PRE> @mozilla.org/rdf/xml-serializer;1
</pre>
<P>From this list, components used often in the Mozilla source code include bookmarks, history, mail and news folders, and address books.    <p>From this list, components used often in the Mozilla source
<BLOCKQUOTE><HR><B>Special URIs</B>    code include bookmarks, history, mail and news folders, and
<P>Mozilla's built-in datasource  <!--INDEX URIs (Universal Resource Identifiers):datasource components -->  <!--INDEX components:URIs --> components have special URIs for access. Here is the format used to determine the URI from the component reference:    address books.</p>
<P>Component:    <blockquote>
<PRE>@mozilla.org/rdf/datasource;1?name=SomeName</PRE>      <hr>
Datasource URI:      <b>Special URIs</b> 
<PRE>rdf:SomeName</PRE>      <p>Mozilla's built-in datasource 
The URI is also accessible as a datasource property:<HR></BLOCKQUOTE>      <!--INDEX URIs (Universal Resource Identifiers):datasource components -->
foo-ds.URI      <!--INDEX components:URIs --> components have special URIs
      for access. Here is the format used to determine the URI from
<H3><A NAME="77083"></A> What Are RDF Interfaces?</H3>      the component reference:</p>
<P>RDF interfaces  <!--INDEX RDF (Resource Description Framework):interfaces:overview -->  <!--INDEX interfaces:RDF:overview --> are interfaces in Mozilla designed to manipulate RDF structures and data. They typically deal with RDF generally, rather than specific sets of data (as in the case of components). A common use for an RDF interface in JavaScript, shown in <A HREF="#77038">Example 10-7</A>, is to use <I>nsIRDFService</I> to retrieve or assert the root node of an RDF datasource.      <p>Component:</p>
<pre>
<P><I>Example 10-7: <A NAME="77038"></A></I>@mozilla.org/rdf/datasource;1?name=SomeName
<I>Creating a root node</I></pre>
<PRE> // get the nsIRDFService interface and assign it to RDF      Datasource URI: 
 RDF = Components.classes</TD><A HREF="MAILTO:[`@mozilla.org/rdf/rdf-service;1">[`@mozilla.org/rdf/rdf-service;1</A>'].<pre>
 rdf:SomeName
 </pre>
       
   <p>The URI, such as <i>rdf:someName</i>, is also accessible as a datasource 
     property: </p>
   <pre>foo-ds.URI</pre>
   <hr>
     </blockquote>
     <h3><a name="77083"></a> What Are RDF Interfaces?</h3>
     <p>RDF interfaces 
     <!--INDEX RDF (Resource Description Framework):interfaces:overview -->
     <!--INDEX interfaces:RDF:overview --> are interfaces in Mozilla
     designed to manipulate RDF structures and data. They typically
     deal with RDF generally, rather than specific sets of data (as
     in the case of components). A common use for an RDF interface
     in JavaScript, shown in <a href="#77038">Example 10-7</a>, is
     to use <i>nsIRDFService</i> to retrieve or assert the root node
     of an RDF datasource.</p>
     <p><i>Example 10-7: <a name="77038"></a></i> <i>Creating a root
     node</i></p>
 <pre>
  // get the nsIRDFService interface and assign it to RDF
  RDF = Components.classes.["@mozilla.org/rdf/rdf-service;1"].
        getService(Components.interfaces.nsIRDFService);         getService(Components.interfaces.nsIRDFService);
  // call the GetResource method from the interface   // call the GetResource method from the interface
 rootResource = RDF.GetResource('urn:root');</PRE> rootResource = RDF.GetResource('urn:root');
</pre>
<P>Like all Mozilla interfaces, RDF interfaces (shown in <A HREF="#77024">Table 10-3</A>) are defined in IDL and can be accessed through XPCOM. The examples in this section use JavaScript and XPConnect to access the components for simplicity, but you can also use these interfaces with C++, as they are often in the actual Mozilla source code. Most interfaces deal with datasources, which drive the use of RDF in Mozilla.    <p>Like all Mozilla interfaces, RDF interfaces (shown in <a
    href="#77024">Table 10-3</a>) are defined in IDL and can be
<P><I>Table 10-3: <A NAME="77024"></A></I>    accessed through XPCOM. The examples in this section use
<I>Mozilla's built-in RDF interfaces</I>    JavaScript and XPConnect to access the components for
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  RDF interface</B></TD>       <TD><B>  Description</B></TD></TR>    simplicity, but you can also use these interfaces with C++, as
<TR><TD>  nsIRDFService</TD>     <TD>  Mostly used for retrieving, datasources, resources, and literals. It also registers and unregisters datasources and resources.</TD></TR>    they are often in the actual Mozilla source code. Most
<TR><TD>  nsIRDFCompositeDataSource</TD>     <TD>  Allows the addition and removal of a datasource from a composite datasource (which may be empty).</TD></TR>    interfaces deal with datasources, which drive the use of RDF in
<TR><TD>  nsIRDFDataSource, nsIRDFPurgeableDataSource, nsIRDFRemoteDataSource</TD>     <TD>  Mostly used for adding, removing, and changing triples in a datasource. It provides the means to change the graph.</TD></TR>    Mozilla.</p>
<TR><TD>  nsIRDFNode, nsIRDFResource, nsIRDFLiteral</TD>     <TD>  Provide an equality function. Values for resources and literals can be retrieved. Objects of these types are retrieved from </TD><TT>nsIRDFService</TT>.</TR>    <p><i>Table 10-3: <a name="77024"></a></i> <i>Mozilla's
<TR><TD>  nsIRDFContainer</TD>     <TD>  Provides vector-like access to an RDF container's elements.</TD></TR>    built-in RDF interfaces</i></p>
<TR><TD>  nsIRDFContainerUtils</TD>     <TD>  Provides container creation and other container-related functions.</TD></TR>    <tt>nsIRDFService</tt>.
<TR><TD>  nsIRDFObserver</TD>     <TD>  Fires events when data is changed in a datasource.</TD></TR>    <table width="100%" border="1">
<TR><TD>  nsIRDFXMLParser, nsIRDFXMLSerializer, nsIRDFXMLSink, nsIRDFXMLSource</TD>     <TD>  Used for working with RDF/XML. Functions are provided for parsing files and serializing content.</TD></TR></TABLE><P>      <tr>
        <td><b>RDF interface</b></td>
<P>The sheer variety of RDF interfaces may seem overwhelming, but all interfaces serve different purposes and are often used in conjunction with one another. In your particular application space, you may find yourself using some subsets of these interfaces constantly and others not at all. This section describes some of the most commonly used functions. You can look up all of interfaces in their entirety <!--INDEX web sites:RDF interfaces -->  at <I><A HREF="http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/">http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/</A></I>.        <td><b>Description</b></td>
<H3><A NAME="77084"></A> nsIRDFService</H3>      </tr>
<P>If you <!--INDEX nsIRDFService interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFService -->  <!--INDEX interfaces:RDF:nsIRDFService -->  will do any sort of RDF processing, you need to use the <I>nsIRDFService</I> interface. It provides the basics for working with datasources, resources, and literals, and is useful when you process RDF data. <I>nsIRDFService</I> can be initialized by using the <TT>getService</TT> method of the <TT>rdf-service</TT> class:      <tr>
<PRE>RDF = Components.<A HREF="MAILTO:classes[`@mozilla.org/rdf/rdf-service;1">classes[`@mozilla.org/rdf/rdf-service;1</A>']        <td>nsIRDFService</td>
getService(Components.interfaces.nsIRDFService);</PRE>        
<P>Once the service is available, it's ready to go to work. Even though no datasource is created yet (in this particular example), the RDF service can still get resources and literals, as shown in the next section.    <td>Mostly used for retrieving datasources, resources, and literals. It also 
<H4><A NAME="77085"></A> Getting a resource</H4>      registers and unregisters datasources and resources.</td>
<P>Once a resource <!--INDEX resources:nsIRDFService interface -->  is created (e.g., with the identifier <TT>urn:root</TT> in <A HREF="#77038">Example 10-7</A>), it needs to be added to a datasource:      </tr>
<PRE>rootResource = RDF.GetResource('urn:root');</PRE>      <tr>
<P>When a resource is already registered under the given identifier (see <A HREF="#77088">"Registering and unregistering datasources</A>," later in this chapter for more information about RDF registration), then <TT> <!--INDEX GetResource function --> GetResource</TT> returns that resource.        <td>nsIRDFCompositeDataSource</td>
<H4><A NAME="77086"></A> Getting an anonymous resource</H4>        <td>Allows the addition and removal of a datasource from a
<P>Anonymous resources are resources with no resource identifier. Here is the creation of a new anonymous resource and a test of its anonymity:        composite datasource (which may be empty).</td>
<PRE>anonResource = RDF.GetAnonymousResource( );      </tr>
       <tr>
         <td>nsIRDFDataSource, nsIRDFPurgeableDataSource,
         nsIRDFRemoteDataSource</td>
         <td>Mostly used for adding, removing, and changing triples
         in a datasource. It provides the means to change the
         graph.</td>
       </tr>
       <tr>
         <td>nsIRDFNode, nsIRDFResource, nsIRDFLiteral</td>
         
     <td>Provide an equality function. Values for resources and literals can be 
       retrieved. Objects of these types are retrieved from nsIRDFService.</td>
       </tr>
       <tr>
         <td>nsIRDFContainer</td>
         <td>Provides vector-like access to an RDF container's
         elements.</td>
       </tr>
       <tr>
         <td>nsIRDFContainerUtils</td>
         <td>Provides container creation and other container-related
         functions.</td>
       </tr>
       <tr>
         <td>nsIRDFObserver</td>
         <td>Fires events when data is changed in a datasource.</td>
       </tr>
       <tr>
         <td>nsIRDFXMLParser, nsIRDFXMLSerializer, nsIRDFXMLSink,
         nsIRDFXMLSource</td>
         <td>Used for working with RDF/XML. Functions are provided
         for parsing files and serializing content.</td>
       </tr>
     </table>
     <p>The sheer variety of RDF interfaces may seem overwhelming,
     but all interfaces serve different purposes and are often used
     in conjunction with one another. In your particular application
     space, you may find yourself using some subsets of these
     interfaces constantly and others not at all. This section
     describes some of the most commonly used functions. You can
     look up all of interfaces in their entirety 
     <!--INDEX web sites:RDF interfaces --> at <i><a href=
     "http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/">http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/</a></i>.</p>
     <h3><a name="77084"></a> nsIRDFService</h3>
     <p>If you <!--INDEX nsIRDFService interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFService -->
     <!--INDEX interfaces:RDF:nsIRDFService --> will do any sort of
     RDF processing, you need to use the <i>nsIRDFService</i>
     interface. It provides the basics for working with datasources,
     resources, and literals, and is useful when you process RDF
     data. <i>nsIRDFService</i> can be initialized by using the
     <tt>getService</tt> method of the <tt>rdf-service</tt>
     class:</p>
 <pre>
 RDF = Components.<a href=
 "MAILTO:classes[`@mozilla.org/rdf/rdf-service;1">classes[`@mozilla.org/rdf/rdf-service;1</a>']
 getService(Components.interfaces.nsIRDFService);
 </pre>
     <p>Once the service is available, it's ready to go to work.
     Even though no datasource is created yet (in this particular
     example), the RDF service can still get resources and literals,
     as shown in the next section.</p>
     <h4><a name="77085"></a> Getting a resource</h4>
     <p>Once a resource 
     <!--INDEX resources:nsIRDFService interface --> is created
     (e.g., with the identifier <tt>urn:root</tt> in <a href=
     "#77038">Example 10-7</a>), it needs to be added to a
     datasource:</p>
 <pre>
 rootResource = RDF.GetResource('urn:root');
 </pre>
     <p>When a resource is already registered under the given
     identifier (see <a href="#77088">"Registering and unregistering
     datasources</a>," later in this chapter for more information
     about RDF registration), then <tt>
     <!--INDEX GetResource function --> GetResource</tt> returns
     that resource.</p>
     <h4><a name="77086"></a> Getting an anonymous resource</h4>
     <p>Anonymous resources are resources with no resource
     identifier. Here is the creation of a new anonymous resource
     and a test of its anonymity:</p>
 <pre>
 anonResource = RDF.GetAnonymousResource( );
 // This would be true. Checking is not necessary, just here for example.  // This would be true. Checking is not necessary, just here for example.
isAnon = RDF.isAnonymousResource(anonResource);</PRE>isAnon = RDF.isAnonymousResource(anonResource);
<P>Typically, these resources are turned into containers, as shown in the next section. Anonymous resources exist when names are not needed and a simple reference to that resource is all that is required.</pre>
<H4><A NAME="77087"></A> Getting a literal</H4>    <p>Typically, these resources are turned into containers, as
<P>The <TT> <!--INDEX GetLiteral function --> GetLiteral</TT> function  <!--INDEX literals:nsIRDFService interface --> returns the given name in the format of a literal, which you can then use to assert into an RDF graph as a resource.    shown in the next section. Anonymous resources exist when names
<PRE>myName = RDF.GetLiteral('Eric');</PRE>    are not needed and a simple reference to that resource is all
<P>Variations on this function are <TT>GetIntLiteral</TT> and <TT>GetDateLiteral</TT>.    that is required.</p>
<H4><A NAME="77088"></A> Registering and unregistering datasources</H4>    <h4><a name="77087"></a> Getting a literal</h4>
<P>If you create  <!--INDEX datasources:registering -->  <!--INDEX registering:datasources -->  <!--INDEX RDF (Resource Description     <p>The <tt><!--INDEX GetLiteral function --> GetLiteral</tt>
Framework):datasources, registering --> a Mozilla application that uses the same datasource or RDF resources in different ways, you may want to register the datasource with Mozilla. When you register a datasource, you register it as a component in Mozilla (see <A HREF="ch08.html#77062">"Component Manager" in Chapter 8</A> for more information on Mozilla's component model), which means it can be accessed and used as easily as any other XPCOM component, and from anywhere in Mozilla.    function <!--INDEX literals:nsIRDFService interface --> returns
<P>To register a datasource, call the <TT> <!--INDEX RegisterDatasource method --> RegisterDatasource</TT> method of the RDF Service. In this example, the datasource already exists and is assigned to a variable named <I>myDatasource</I>:    the given name in the format of a literal, which you can then
<PRE>RDF.RegisterDataSource(myDatasource, false);</PRE>    use to assert into an RDF graph as a resource.</p>
<P>In this case, <I>myDatasource</I> is the datasource name, and the <TT>false</TT> parameter specifies that this datasource is not replacing a datasource with the same name. Once a datasource is registered with the component manager in this way, it can be retrieved by name and associated with another instance:<pre>
<PRE>secondDatasource = anotherRDF.GetDataSource("My Datasource");</PRE>myName = RDF.GetLiteral('Eric');
<P>To unregister a datasource from the RDF Service, pass the datasource into the <TT>UnRegisterDataSource</TT> function:</pre>
<PRE>RDF.UnRegisterDataSource(myDatasource);</PRE>    <p>Variations on this function are <tt>GetIntLiteral</tt> and
<P>Once it's unregistered, a datasource is no longer available to other instances of the RDF Service. Registered resources work the same way as datasources in the RDF Service: if a resource is registered with the RDF Service, then it is available in every instance of RDF Service. To get two different instances of the same registered datasource and unregister its use:    <tt>GetDateLiteral</tt>.</p>
<PRE>newResource = RDF.GetResource('my.resource');    <h4><a name="77088"></a> Registering and unregistering
     datasources</h4>
     <p>If you create <!--INDEX datasources:registering --> 
     <!--INDEX registering:datasources --> 
     <!--INDEX RDF (Resource Description 
     Framework):datasources, registering --> a Mozilla application
     that uses the same datasource or RDF resources in different
     ways, you may want to register the datasource with Mozilla.
     When you register a datasource, you register it as a component
     in Mozilla (see <a href="ch08.html#77062">"Component Manager"
     in Chapter 8</a> for more information on Mozilla's component
     model), which means it can be accessed and used as easily as
     any other XPCOM component, and from anywhere in Mozilla.</p>
     <p>To register a datasource, call the <tt>
     <!--INDEX RegisterDatasource method --> RegisterDatasource</tt>
     method of the RDF Service. In this example, the datasource
     already exists and is assigned to a variable named
     <i>myDatasource</i>:</p>
 <pre>
 RDF.RegisterDataSource(myDatasource, false);
 </pre>
     <p>In this case, <i>myDatasource</i> is the datasource name,
     and the <tt>false</tt> parameter specifies that this datasource
     is not replacing a datasource with the same name. Once a
     datasource is registered with the component manager in this
     way, it can be retrieved by name and associated with another
     instance:</p>
 <pre>
 secondDatasource = anotherRDF.GetDataSource("My Datasource");
 </pre>
     <p>To unregister a datasource from the RDF Service, pass the
     datasource into the <tt>UnRegisterDataSource</tt> function:</p>
 <pre>
 RDF.UnRegisterDataSource(myDatasource);
 </pre>
     <p>Once it's unregistered, a datasource is no longer available
     to other instances of the RDF Service. Registered resources
     work the same way as datasources in the RDF Service: if a
     resource is registered with the RDF Service, then it is
     available in every instance of RDF Service. To get two
     different instances of the same registered datasource and
     unregister its use:</p>
 <pre>
 newResource = RDF.GetResource('my.resource');
 RDF.RegisterResource(newResource,false);  RDF.RegisterResource(newResource,false);
 notNewResource = RDF.GetResource('my.resource');  notNewResource = RDF.GetResource('my.resource');
RDF.UnRegisterResource(notNewResource);</PRE>RDF.UnRegisterResource(notNewResource);
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER></pre>
<P>If you register resources and datasources, be sure to use the <I>overwrite</I> Boolean variable on <TT>RegisterDataSource</TT> and <TT>RegisterResource</TT> to avoid overwriting existing datasources.<P></BLOCKQUOTE>    <blockquote>
<H4><A NAME="77089"></A> Getting a remote datasource</H4>      <div class="c21">
<P>Finally, <I>nsIRDFService</I> provides <!--INDEX datasources:remote, getting -->  <!--INDEX remote datasources, getting -->  a useful method that loads a datasource from a remote server, which is a process that occurs asynchronously. Compared to forthcoming discussions about datasource loading, <TT>GetDataSource</TT> is a real shortcut:        NOTE
<PRE>remoteDatasource = RDF.GetDataSource('<A HREF="http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</A>');</PRE>      </div>
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>      <p>If you register resources and datasources, be sure to use
<P>Remember that RDF files requested in this way must be set with the text/rdf MIME type on the web server to load properly.<P></BLOCKQUOTE>      the <i>overwrite</i> Boolean variable on
<H3><A NAME="77090"></A> nsIRDFCompositeDataSource</H3>      <tt>RegisterDataSource</tt> and <tt>RegisterResource</tt> to
<P>When you work  <!--INDEX nsIRDFCompositeDataSource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFCompositeDataSource -->  <!--INDEX interfaces:RDF:nsIRDFCompositeDataSource --> with multiple datasources, you can make things easier by grouping them, which <I>nsIRDFCompositeDataSource</I> allows you to do. This functionality aggregates data in a number of Mozilla's applications. To get this interface, invoke:      avoid overwriting existing datasources.</p>
<PRE>composite_datasource    </blockquote>
     <h4><a name="77089"></a> Getting a remote datasource</h4>
     <p>Finally, <i>nsIRDFService</i> provides 
     <!--INDEX datasources:remote, getting --> 
     <!--INDEX remote datasources, getting --> a useful method that
     loads a datasource from a remote server, which is a process
     that occurs asynchronously. Compared to forthcoming discussions
     about datasource loading, <tt>GetDataSource</tt> is a real
     shortcut:</p>
 <pre>
 remoteDatasource = RDF.GetDataSource('<a href=
 "http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</a>');
 </pre>
     <blockquote>
       <div class="c21">
         NOTE
       </div>
       <p>Remember that RDF files requested in this way must be set
       with the text/rdf MIME type on the web server to load
       properly.</p>
     </blockquote>
     <h3><a name="77090"></a> nsIRDFCompositeDataSource</h3>
     <p>When you work 
     <!--INDEX nsIRDFCompositeDataSource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFCompositeDataSource -->
     <!--INDEX interfaces:RDF:nsIRDFCompositeDataSource --> with
     multiple datasources, you can make things easier by grouping
     them, which <i>nsIRDFCompositeDataSource</i> allows you to do.
     This functionality aggregates data in a number of Mozilla's
     applications. To get this interface, invoke:</p>
 <pre>
 composite_datasource
 = '@mozilla.org/rdf/datasource;1?name=composite-datasource';  = '@mozilla.org/rdf/datasource;1?name=composite-datasource';
 compDataSource = Components.classes[composite_datasource]  compDataSource = Components.classes[composite_datasource]
getService(Components.interfaces.nsIRDFCompositeDataSource);</PRE>getService(Components.interfaces.nsIRDFCompositeDataSource);
<P>Once you have the interface, adding and removing datasources from the composite is easy. You can also enumerate the datasources by using the <TT>getNext</TT> method. <A HREF="#77040">Example 10-8</A> demonstrates how to add, remove, and cycle through datasources.</pre>
    <p>Once you have the interface, adding and removing datasources
<P><I>Example 10-8: <A NAME="77040"></A></I>    from the composite is easy. You can also enumerate the
<I>Manipulating datasources</I>    datasources by using the <tt>getNext</tt> method. <a href=
<PRE> compDataSource.AddDataSource(datasource1);    "#77040">Example 10-8</a> demonstrates how to add, remove, and
     cycle through datasources.</p>
     <p><i>Example 10-8: <a name="77040"></a></i> <i>Manipulating
     datasources</i></p>
 <pre>
  compDataSource.AddDataSource(datasource1);
  compDataSource.AddDataSource(datasource2);   compDataSource.AddDataSource(datasource2);
  compDataSource.AddDataSource(datasource3);   compDataSource.AddDataSource(datasource3);
  compDataSource.RemoveDataSource(datasource1);   compDataSource.RemoveDataSource(datasource1);
Line 499  getService(Components.interfaces.nsIRDFC Line 1269  getService(Components.interfaces.nsIRDFC
  datasource2 = allDataSources.getNext( );   datasource2 = allDataSources.getNext( );
  datasource2.QueryInterface(Components.interfaces.nsIRDFDataSource);   datasource2.QueryInterface(Components.interfaces.nsIRDFDataSource);
  datasource3 = allDataSources.getNext( );   datasource3 = allDataSources.getNext( );
 datasource3.QueryInterface(Components.interfaces.nsIRDFDataSource);</PRE> datasource3.QueryInterface(Components.interfaces.nsIRDFDataSource);
</pre>
<P>In <A HREF="#77040">Example 10-8</A>, <TT>allDataSources</TT> is an <I>nsISimpleEnumerator</I> returned by the <TT>GetDataSources</TT> method on the composite datasource. <TT>datasource1</TT> is removed from the composite, and then the remaining datasources are cycled through. This step provides a way to iterate through a collection of datasources. <I>nsIRDFCompositeDatasource</I> also inherits the many functions of <I>nsIRDFDataSource</I>; refer to the section <A HREF="#77091">"nsIRDFDataSource</A>" for more information.    <p>In <a href="#77040">Example 10-8</a>,
<H3><A NAME="77091"></A> nsIRDFDataSource</H3>    <tt>allDataSources</tt> is an <i>nsISimpleEnumerator</i>
<P>The <I> <!--INDEX nsIRDFDataSource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFDataSource -->  <!--INDEX interfaces:RDF:nsIRDFDataSource --> nsIRDFDataSource</I> interface is large, with twenty functions and one attribute (<TT>URI</TT>), so it's one of the most common interfaces used to manipulate RDF data. <I>nsIRDFDataSource</I> contains all the components in <A HREF="#77036">Example 10-6</A> with "datasource" in their contract IDs, along with other common components:    returned by the <tt>GetDataSources</tt> method on the composite
<PRE>@mozilla.org/browser/bookmarks-service;1    datasource. <tt>datasource1</tt> is removed from the composite,
     and then the remaining datasources are cycled through. This
     step provides a way to iterate through a collection of
     datasources. <i>nsIRDFCompositeDatasource</i> also inherits the
     many functions of <i>nsIRDFDataSource</i>; refer to the section
     <a href="#77091">"nsIRDFDataSource</a>" for more
     information.</p>
     <h3><a name="77091"></a> nsIRDFDataSource</h3>
     <p>The <i><!--INDEX nsIRDFDataSource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFDataSource -->
     <!--INDEX interfaces:RDF:nsIRDFDataSource -->
     nsIRDFDataSource</i> interface is large, with twenty functions
     and one attribute (<tt>URI</tt>), so it's one of the most
     common interfaces used to manipulate RDF data.
     <i>nsIRDFDataSource</i> contains all the components in <a href=
     "#77036">Example 10-6</a> with "datasource" in their contract
     IDs, along with other common components:</p>
 <pre>
 @mozilla.org/browser/bookmarks-service;1
 @mozilla.org/related-links-handler;1  @mozilla.org/related-links-handler;1
 @mozilla.org/browser/localsearch-service;1  @mozilla.org/browser/localsearch-service;1
 @mozilla.org/registry-viewer;1  @mozilla.org/registry-viewer;1
@mozilla.org/browser/global-history;1</PRE>@mozilla.org/browser/global-history;1
<P>The <I>nsIRDFDataSource</I> interface is meant to handle some of the core interaction with the datasource. APIs such as <TT>URI</TT>, <TT>GetTarget</TT>, <TT>Assert</TT>, and <TT>Change</TT> are helpful for working on the RDF graph itself. For example, the <TT>@mozilla.org/rdf/datasource;1?name=in-memory-datasource</TT> RDF component demonstrates the use of the <I>nsIRDFDataSource</I> interface. When this component is created, it's a blank datasource in memory, into which objects are inserted, changed, and removed. You can access the <I>nsIRDFDataSource</I> interface from the RDF component by first constructing an RDF graph in the in-memory datasource:</pre>
<PRE>mem = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';    <p>The <i>nsIRDFDataSource</i> interface is meant to handle
     some of the core interaction with the datasource. APIs such as
     <tt>URI</tt>, <tt>GetTarget</tt>, <tt>Assert</tt>, and
     <tt>Change</tt> are helpful for working on the RDF graph
     itself. For example, the
     <tt>@mozilla.org/rdf/datasource;1?name=in-memory-datasource</tt>
     RDF component demonstrates the use of the
     <i>nsIRDFDataSource</i> interface. When this component is
     created, it's a blank datasource in memory, into which objects
     are inserted, changed, and removed. You can access the
     <i>nsIRDFDataSource</i> interface from the RDF component by
     first constructing an RDF graph in the in-memory
     datasource:</p>
 <pre>
 mem = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
 datasource = Components.classes[mem].  datasource = Components.classes[mem].
createInstance(Components.interfaces.nsIRDFDataSource);</PRE>createInstance(Components.interfaces.nsIRDFDataSource);
<P>Of the twenty functions (found at <I><A HREF="http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl">http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl</A></I>) in this interface, we show only a handful here:</pre>
<UL><P><LI>Assertion and removal<P>    <p>Of the twenty functions (found at <i><a href=
<P><LI>Changing values<P>    "http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl">
<P><LI>Moving triples<P>    http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl</a></i>)
<P><LI>HasAssertion<P>    in this interface, we show only a handful here:</p>
<P><LI>GetTarget<P>    <ul>
<P><LI>GetSource<P></UL>      <li>Assertion and removal</li>
<P>The main purpose of the <I>nsIRDFDatasource</I> interface is to work with RDF triples inside a datasource, allowing you to change that datasource's RDF graph.      <li>Changing values</li>
<H4><A NAME="77092"></A> Assertion and removal</H4>      <li>Moving triples</li>
<P>Recall from the <!--INDEX triples:nsIRDFDataSource interface -->  <A HREF="#77065">"RDF triples: subject, predicate, and object</A>" section, earlier in this chapter, that triples are RDF statements in which the relationship between the subject, predicate, and object is more strictly defined. In the interface code, a triple's elements are all typically defined as resources rather than plain URIs, which means they can be asserted into a datasource in the particular sequence that makes them meaningful as parts of a triple:      <li>HasAssertion</li>
<PRE>rootSubject = RDF.GetResource('urn:root');      <li>GetTarget</li>
predicate = RDF.GetResource('<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#chapters');      <li>GetSource</li>
     </ul>
     <p>The main purpose of the <i>nsIRDFDatasource</i> interface is
     to work with RDF triples inside a datasource, allowing you to
     change that datasource's RDF graph.</p>
     <h4><a name="77092"></a> Assertion and removal</h4>
     <p>Recall from the 
     <!--INDEX triples:nsIRDFDataSource interface --> <a href=
     "#77065">"RDF triples: subject, predicate, and object</a>"
     section, earlier in this chapter, that triples are RDF
     statements in which the relationship between the subject,
     predicate, and object is more strictly defined. In the
     interface code, a triple's elements are all typically defined
     as resources rather than plain URIs, which means they can be
     asserted into a datasource in the particular sequence that
     makes them meaningful as parts of a triple:</p>
 <pre>
 rootSubject = RDF.GetResource('urn:root');
 predicate = RDF.GetResource('<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
 object = RDF.GetResource('Chapter1');  object = RDF.GetResource('Chapter1');
datasource.Assert(rootSubject,predicate,object,true);</PRE>datasource.Assert(rootSubject,predicate,object,true);
<P>Once you assert the statement's elements into the datasource in this way, the datasource contains the triple. The <TT>truth</TT> value parameter in the last slot indicates that the given node is "locked" and thus cannot be overwritten.</pre>
<P>Removing a triple from the datasource is as easy as adding it. If you try to remove a triple that doesn't exist, your request is ignored and no error messages are raised. To unassert a triple in the datasource, use:    <p>Once you assert the statement's elements into the datasource
<PRE>rootSubject = RDF.GetResource('urn:root');    in this way, the datasource contains the triple. The
predicate = RDF.GetResource('<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#chapters');    <tt>truth</tt> value parameter in the last slot indicates that
     the given node is "locked" and thus cannot be overwritten.</p>
     <p>Removing a triple from the datasource is as easy as adding
     it. If you try to remove a triple that doesn't exist, your
     request is ignored and no error messages are raised. To
     unassert a triple in the datasource, use:</p>
 <pre>
 rootSubject = RDF.GetResource('urn:root');
 predicate = RDF.GetResource('<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
 object = RDF.GetResource('Chapter8');  object = RDF.GetResource('Chapter8');
datasource.Unassert(rootSubject,predicate,object);</PRE>datasource.Unassert(rootSubject,predicate,object);
<H4><A NAME="77093"></A> Changing values</H4></pre>
<P>Changing values  <!--INDEX literals:values, changing -->  <!--INDEX datasources:values, changing --> in a datasource is also very easy. Assert and change a literal in the datasource as follows:    <h4><a name="77093"></a> Changing values</h4>
<PRE>subject = RDF.GetResource('Chapter1');    <p>Changing values <!--INDEX literals:values, changing --> 
predicate = RDF.GetResource('<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#title');    <!--INDEX datasources:values, changing --> in a datasource is
     also very easy. Assert and change a literal in the datasource
     as follows:</p>
 <pre>
 subject = RDF.GetResource('Chapter1');
 predicate = RDF.GetResource('<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#title');
 object = RDF.GetLiteral('Mozilla as a Platform');  object = RDF.GetLiteral('Mozilla as a Platform');
 datasource.Assert(subject,predicate,object,true);  datasource.Assert(subject,predicate,object,true);
 newObject = RDF.GetLiteral('Mozilla is a cool Platform!');  newObject = RDF.GetLiteral('Mozilla is a cool Platform!');
datasource.Change(subject,predicate,newObject,);</PRE>datasource.Change(subject,predicate,newObject,);
<P>If working with triples seems hard in the template generation, their use in these examples-where adding to and changing the parts is so easy-may make things clearer.</pre>
<H4><A NAME="77094"></A> Moving triples</H4>    <p>If working with triples seems hard in the template
<P>Moving a triple <!--INDEX triples:moving -->  in a datasource also requires some simple code. This example moves the asserted triple in the previous section:    generation, their use in these examples-where adding to and
<PRE>newSubject = RDF.GetResource('Chapter99');    changing the parts is so easy-may make things clearer.</p>
     <h4><a name="77094"></a> Moving triples</h4>
     <p>Moving a triple <!--INDEX triples:moving --> in a datasource
     also requires some simple code. This example moves the asserted
     triple in the previous section:</p>
 <pre>
 newSubject = RDF.GetResource('Chapter99');
 // Moving from Chapter1 to Chapter99  // Moving from Chapter1 to Chapter99
datasource.Move(subject,newSubject,predicate,object);</PRE>datasource.Move(subject,newSubject,predicate,object);
<H4><A NAME="77095"></A> HasAssertion</H4></pre>
<P>This next example <!--INDEX HasAssertion function -->  checks if the previous statement still exists in the datasource.    <h4><a name="77095"></a> HasAssertion</h4>
<PRE>datasource.HasAssertion(newSubject,predicate,object,true);</PRE>    <p>This next example <!--INDEX HasAssertion function --> checks
<P>This function is useful when you create new statements and resources and want to make sure you are not overwriting pre-existing resources.    if the previous statement still exists in the datasource.</p>
<H4><A NAME="77096"></A> GetTarget</H4><pre>
<P>The <TT> <!--INDEX GetTarget method --> GetTarget</TT> method returns the resource's property value (i.e., the object). Given the RDF statement "(Eric) wrote (a book)," for example, the <TT>GetTarget</TT> method would input "Eric" and "wrote" and get back the object "a book." Once again, the example code is based on the previous examples:datasource.HasAssertion(newSubject,predicate,object,true);
<PRE>object = datasource.GetTarget(newSubject,predicate,true);</pre>
     <p>This function is useful when you create new statements and
     resources and want to make sure you are not overwriting
     pre-existing resources.</p>
     <h4><a name="77096"></a> GetTarget</h4>
     <p>The <tt><!--INDEX GetTarget method --> GetTarget</tt> method
     returns the resource's property value (i.e., the object). Given
     the RDF statement "(Eric) wrote (a book)," for example, the
     <tt>GetTarget</tt> method would input "Eric" and "wrote" and
     get back the object "a book." Once again, the example code is
     based on the previous examples:</p>
 <pre>
 object = datasource.GetTarget(newSubject,predicate,true);
 objects = datasource.GetTargets(rootSubject,predicate,true);  objects = datasource.GetTargets(rootSubject,predicate,true);
// objects is an nsIEnumeration of the object and its properties</PRE>// objects is an nsIEnumeration of the object and its properties
<P>In addition to <TT>GetTarget</TT>, as seen above, a <TT>GetTargets</TT> function returns an object and its properties in an enumeration. This function can be very handy for quick access to resources with fewer function calls.</pre>
<H4><A NAME="77097"></A> GetSource</H4>    <p>In addition to <tt>GetTarget</tt>, as seen above, a
<P><TT> <!--INDEX GetSource method --> GetSource</TT> is the inverse of <TT>GetTarget</TT>. Whereas <TT>GetTarget</TT> returns an object, <TT>GetSource</TT> returns the subject attached to an object. Given the RDF statement "(Eric) wrote (a book)" again, in other words, the <TT>GetSource</TT> method would input "wrote" and "a book" and get back the statement subject "Eric."    <tt>GetTargets</tt> function returns an object and its
<PRE>subject = datasource.GetSource(object,predicate,true);    properties in an enumeration. This function can be very handy
     for quick access to resources with fewer function calls.</p>
     <h4><a name="77097"></a> GetSource</h4>
     <p><tt><!--INDEX GetSource method --> GetSource</tt> is the
     inverse of <tt>GetTarget</tt>. Whereas <tt>GetTarget</tt>
     returns an object, <tt>GetSource</tt> returns the subject
     attached to an object. Given the RDF statement "(Eric) wrote (a
     book)" again, in other words, the <tt>GetSource</tt> method
     would input "wrote" and "a book" and get back the statement
     subject "Eric."</p>
 <pre>
 subject = datasource.GetSource(object,predicate,true);
 subjects = datasource.GetSources(object,predicate,true);  subjects = datasource.GetSources(object,predicate,true);
// subjects is an nsIEnumeration of the subject and its properties</PRE>// subjects is an nsIEnumeration of the subject and its properties
<P>When you create RDF statements with assertions or work with in-memory datasources, it is often difficult to remember the shape of the graph, which statements exist about which resources, or which objects are attached to which subjects. These "getter" methods can help you verify the shape of your graph.</pre>
<H3><A NAME="77098"></A> nsIRDFRemoteDataSource</H3>    <p>When you create RDF statements with assertions or work with
<P>The <!--INDEX nsIRDFRemoteDataSource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFRemoteDataSource -->  <!--INDEX interfaces:RDF:nsIRDFRemoteDataSource -->  <A HREF="#77084">"nsIRDFService</A>" section (earlier in this chapter) showed how to load a datasource from a remote server simply. If you want control over that datasource, you can manage it by using the <I>nsIRDFRemoteDatasource</I> to set up a remote datasource:    in-memory datasources, it is often difficult to remember the
<PRE>xml = '@mozilla.org/rdf/datasource;1?name=xml-datasource';    shape of the graph, which statements exist about which
     resources, or which objects are attached to which subjects.
     These "getter" methods can help you verify the shape of your
     graph.</p>
     <h3><a name="77098"></a> nsIRDFRemoteDataSource</h3>
     <p>The <!--INDEX nsIRDFRemoteDataSource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFRemoteDataSource -->
     <!--INDEX interfaces:RDF:nsIRDFRemoteDataSource --> <a href=
     "#77084">"nsIRDFService</a>" section (earlier in this chapter)
     showed how to load a datasource from a remote server simply. If
     you want control over that datasource, you can manage it by
     using the <i>nsIRDFRemoteDatasource</i> to set up a remote
     datasource:</p>
 <pre>
 xml = '@mozilla.org/rdf/datasource;1?name=xml-datasource';
 datasource = Components.classes[xml].  datasource = Components.classes[xml].
 createInstance(Components.interfaces.nsIRDFRemoteDataSource);  createInstance(Components.interfaces.nsIRDFRemoteDataSource);
datasource.Init('<A HREF="http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</A>');datasource.Init('<a href=
datasource.Refresh(false);</PRE>"http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</a>');
<P>In this example, the <TT>Init</TT> and <TT>Refresh</TT> methods control the datasource on the server. In addition to these methods, you can call the <TT>Flush</TT> method to flush the data that's been changed and reload, or you can check whether the datasource is loaded by using the <TT>loaded</TT> property:datasource.Refresh(false);
<PRE>if (datasource.loaded) {</pre>
     <p>In this example, the <tt>Init</tt> and <tt>Refresh</tt>
     methods control the datasource on the server. In addition to
     these methods, you can call the <tt>Flush</tt> method to flush
     the data that's been changed and reload, or you can check
     whether the datasource is loaded by using the <tt>loaded</tt>
     property:</p>
 <pre>
 if (datasource.loaded) {
 // Do something  // Do something
}</PRE>}
<P>Built-in datasources that implement <I>nsIRDFRemoteDataSource</I> (and other necessary interfaces) and do their own data handling include:</pre>
<PRE>@mozilla.org/rdf/datasource;1?name=history    <p>Built-in datasources that implement
     <i>nsIRDFRemoteDataSource</i> (and other necessary interfaces)
     and do their own data handling include:</p>
 <pre>
 @mozilla.org/rdf/datasource;1?name=history
 @mozilla.org/browser/bookmarks-service;1  @mozilla.org/browser/bookmarks-service;1
 @mozilla.org/autocompleteSession;1?type=history  @mozilla.org/autocompleteSession;1?type=history
 @mozilla.org/browser/global-history;1  @mozilla.org/browser/global-history;1
@mozilla.org/rdf/datasource;1?name=bookmarks</PRE>@mozilla.org/rdf/datasource;1?name=bookmarks
<H3><A NAME="77099"></A> nsIRDFPurgeableDataSource</H3></pre>
<P>Using  <!--INDEX nsIRDFPurgeableDataSource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFPurgeableDataSource -->  <!--INDEX interfaces:RDF:nsIRDFPurgeableDataSource --> the <I>nsIRDFPurgeableDatasource</I> interface allows you to delete a whole section of an existing in-memory datasource in one fell swoop. This means that all relatives-all statements derived from that node-are removed. When you work with large in-memory datasources (such as email systems), the using interface can manipulate the data efficiently. The <TT>Sweep( )</TT> method can delete a section that is marked in the datasource.    <h3><a name="77099"></a> nsIRDFPurgeableDataSource</h3>
<PRE>datasource.    <p>Using <!--INDEX nsIRDFPurgeableDataSource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFPurgeableDataSource -->
     <!--INDEX interfaces:RDF:nsIRDFPurgeableDataSource --> the
     <i>nsIRDFPurgeableDatasource</i> interface allows you to delete
     a whole section of an existing in-memory datasource in one fell
     swoop. This means that all relatives-all statements derived
     from that node-are removed. When you work with large in-memory
     datasources (such as email systems), the using interface can
     manipulate the data efficiently. The <tt>Sweep( )</tt> method
     can delete a section that is marked in the datasource.</p>
 <pre>
 datasource.
 QueryInterface(Components.interfaces.nsIRDFPurgeableDataSource);  QueryInterface(Components.interfaces.nsIRDFPurgeableDataSource);
 rootSubject = RDF.GetResource('urn:root');  rootSubject = RDF.GetResource('urn:root');
predicate = RDF.GetResource('<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#chapters');predicate = RDF.GetResource('<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
 object = RDF.GetResource('Chapter1');  object = RDF.GetResource('Chapter1');
 datasource.Mark(rootSubject,predicate,object,true);  datasource.Mark(rootSubject,predicate,object,true);
datasource.Sweep( );</PRE>datasource.Sweep( );
<P>In this instance, a statement about a chapter in a book is marked and then removed from the datasource. You can also mark more than one node before sweeping.</pre>
<H3><A NAME="77100"></A> nsIRDFNode, nsIRDFResource, and nsIRDFLiteral</H3>    <p>In this instance, a statement about a chapter in a book is
<P>These types of objects come from only a few different places. Here are all the functions that can return the resource of a literal:    marked and then removed from the datasource. You can also mark
<PRE>nsIRDFService.GetResource    more than one node before sweeping.</p>
     <h3><a name="77100"></a> nsIRDFNode, nsIRDFResource, and
     nsIRDFLiteral</h3>
     <p>These types of objects come from only a few different
     places. Here are all the functions that can return the resource
     of a literal:</p>
 <pre>
 nsIRDFService.GetResource
 nsIRDFService.GetAnonymousResource  nsIRDFService.GetAnonymousResource
 nsIRDFService.GetLiteral  nsIRDFService.GetLiteral
 nsIRDFDataSource.GetSource  nsIRDFDataSource.GetSource
nsIRDFDataSource.GetTarget</PRE>nsIRDFDataSource.GetTarget
<P><I>nsIRDFNode <!--INDEX nsIRDFNode interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFNode -->  <!--INDEX interfaces:RDF:nsIRDFNode --> </I> is the parent of <I>nsIRDFResource</I> and <I>nsIRDFLiteral</I>. It is not used often because it's sole function is to test equality:</pre>
<PRE>isEqual = resource1.EqualsNode(resource2);</PRE>    <p><i>nsIRDFNode <!--INDEX nsIRDFNode interface --> 
<P>The other two interfaces inherit this function automatically. <TT>EqualsNode</TT> tests the equivalency of two resources, which can be useful when you try to put together different statements (e.g., "Eric wrote a book" and "[This] book is about XML") and want to verify that a resource like "book" is the same in both cases.    <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFNode -->
<H4><A NAME="77101"></A> nsIRDFResource</H4>    <!--INDEX interfaces:RDF:nsIRDFNode --></i> is the parent of
<P>Like <!--INDEX nsIRDFResource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFResource -->  <!--INDEX interfaces:RDF:nsIRDFResource -->  <I>nsIRDFNode</I>, <I>nsIRDFResource</I> is a minimalist interface. Here are the functions and the property available in a resource from the <I>nsIRDFResource</I> interface:    <i>nsIRDFResource</i> and <i>nsIRDFLiteral</i>. It is not used
<PRE>resource = RDF.GetAnonymousResource( );    often because it's sole function is to test equality:</p>
 <pre>
 isEqual = resource1.EqualsNode(resource2);
 </pre>
     <p>The other two interfaces inherit this function
     automatically. <tt>EqualsNode</tt> tests the equivalency of two
     resources, which can be useful when you try to put together
     different statements (e.g., "Eric wrote a book" and "[This]
     book is about XML") and want to verify that a resource like
     "book" is the same in both cases.</p>
     <h4><a name="77101"></a> nsIRDFResource</h4>
     <p>Like <!--INDEX nsIRDFResource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFResource -->
     <!--INDEX interfaces:RDF:nsIRDFResource --> <i>nsIRDFNode</i>,
     <i>nsIRDFResource</i> is a minimalist interface. Here are the
     functions and the property available in a resource from the
     <i>nsIRDFResource</i> interface:</p>
 <pre>
 resource = RDF.GetAnonymousResource( );
 // get the resource value, something like 'rdf:#$44RG7'  // get the resource value, something like 'rdf:#$44RG7'
 resourceIdentifierString = resource.Value;  resourceIdentifierString = resource.Value;
 // compare the resource to an identifier  // compare the resource to an identifier
 isTrue = resourceEqualsString(resourceIdentifierString);  isTrue = resourceEqualsString(resourceIdentifierString);
 // Give the resource a real name.  // Give the resource a real name.
resource.Init('Eric');</PRE>resource.Init('Eric');
<H4><A NAME="77102"></A> nsIRDFLiteral</H4></pre>
<P>A literal's  <!--INDEX nsIRDFLiteral interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFLiteral -->  <!--INDEX interfaces:RDF:nsIRDFLiteral --> value can be read but not written. To change the value of a literal, make a new literal and set it properly:    <h4><a name="77102"></a> nsIRDFLiteral</h4>
<PRE>aValue = literal.Value;</PRE>    <p>A literal's <!--INDEX nsIRDFLiteral interface --> 
<P>Note that <TT>aValue</TT> could be a string or an integer in this case. The base type conversion, based on the data's format, is done automatically.    <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFLiteral -->
<H3><A NAME="77103"></A> nsIRDFContainerUtils</H3>    <!--INDEX interfaces:RDF:nsIRDFLiteral --> value can be read
<P>This interface <!--INDEX nsIRDFContainerUtils interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainerUtils -->  <!--INDEX interfaces:RDF:nsIRDFContainerUtils -->  facilitates the creation of containers and provides other container-related functions. It provides functions that make and work with a <TT>sequence</TT>, <TT>bag</TT>, and <TT>alternative</TT>. (The functions work the same way for all types of containers, so only <TT>sequence</TT> is covered here.) To create an instance of <I>nsIRDFContainerUtils</I>, use the following:    but not written. To change the value of a literal, make a new
<PRE>containerUtils = Components.classes['@mozilla.org/rdf/container-utils;1'    literal and set it properly:</p>
getService(Components.interfaces.nsIRDFContainerUtils);</PRE><pre>
<P>Once you create an anonymous resource, you can create a sequence from it. Then you can test the type of the container and see whether it's empty:aValue = literal.Value;
<PRE>// create an anonymous resource</pre>
     <p>Note that <tt>aValue</tt> could be a string or an integer in
     this case. The base type conversion, based on the data's
     format, is done automatically.</p>
     <h3><a name="77103"></a> nsIRDFContainerUtils</h3>
     <p>This interface <!--INDEX nsIRDFContainerUtils interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainerUtils -->
     <!--INDEX interfaces:RDF:nsIRDFContainerUtils --> facilitates
     the creation of containers and provides other container-related
     functions. It provides functions that make and work with a
     <tt>sequence</tt>, <tt>bag</tt>, and <tt>alternative</tt>. (The
     functions work the same way for all types of containers, so
     only <tt>sequence</tt> is covered here.) To create an instance
     of <i>nsIRDFContainerUtils</i>, use the following:</p>
 <pre>
 containerUtils = Components.classes['@mozilla.org/rdf/container-utils;1'].
 getService(Components.interfaces.nsIRDFContainerUtils);
 </pre>
     <p>Once you create an anonymous resource, you can create a
     sequence from it. Then you can test the type of the container
     and see whether it's empty:</p>
 <pre>
 // create an anonymous resource
 anonResource = RDF.GetAnonymousResource( );  anonResource = RDF.GetAnonymousResource( );
 // create a sequence from that resource  // create a sequence from that resource
 aSequence = containerUtils.MakeSeq(datasource,anonResource);  aSequence = containerUtils.MakeSeq(datasource,anonResource);
Line 626  aSequence = containerUtils.MakeSeq(datas Line 1576  aSequence = containerUtils.MakeSeq(datas
 // (all of these are true)  // (all of these are true)
 isContainer = containerUtils.isContainer(datasource,anonResource);  isContainer = containerUtils.isContainer(datasource,anonResource);
 isSequence = containerUtils.isSequence(datasource,anonResource);  isSequence = containerUtils.isSequence(datasource,anonResource);
isEmpty = containerUtils.isEmpty(datasource,anonResource);</PRE>isEmpty = containerUtils.isEmpty(datasource,anonResource);
<P>Note that the sequence object is not passed into the functions performing the test in the previous example; the resource containing the sequence is passed in. Although <TT>aSequence</TT> and <TT>anonResource</TT> are basically the same resource, their data types are different. <TT>isContainer</TT>, <TT>isSequence</TT>, and <TT>isEmpty</TT> can be used more easily with other RDF functions when a resource is used as a parameter:</pre>
<PRE>object = datasource.GetTarget(subject,predicate,true);    <p>Note that the sequence object is not passed into the
     functions performing the test in the previous example; the
     resource containing the sequence is passed in. Although
     <tt>aSequence</tt> and <tt>anonResource</tt> are basically the
     same resource, their data types are different.
     <tt>isContainer</tt>, <tt>isSequence</tt>, and <tt>isEmpty</tt>
     can be used more easily with other RDF functions when a
     resource is used as a parameter:</p>
 <pre>
 object = datasource.GetTarget(subject,predicate,true);
 if(RDF.isAnonymousResource(object))  if(RDF.isAnonymousResource(object))
 {  {
 isSeq = containerUtils.IsSeq(datasource,object);  isSeq = containerUtils.IsSeq(datasource,object);
}</PRE>}
<P>The RDF container utilities also provide an indexing function. <TT>indexOf</TT> is useful for checking if an element exists in a container resource:</pre>
<PRE>indexNumber =    <p>The RDF container utilities also provide an indexing
     function. <tt>indexOf</tt> is useful for checking if an element
     exists in a container resource:</p>
 <pre>
 indexNumber =
 containerUtils.indexOf(datasource,object,RDF.GetLiteral('Eric'));  containerUtils.indexOf(datasource,object,RDF.GetLiteral('Eric'));
 if(index != -1)  if(index != -1)
alert('Eric exists in this container');</PRE>alert('Eric exists in this container');
<H3><A NAME="77104"></A> nsIRDFContainer</H3></pre>
<P>This interface  <!--INDEX nsIRDFContainer interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainer -->  <!--INDEX interfaces:RDF:nsIRDFContainer --> provides vector-like access to an RDF container's elements.<A NAME="b291"></A><A HREF="#291">[*]</A> The <I>nsIRDFContainer</I> interface allows you to add, look up, and remove elements from a container once you create it.    <h3><a name="77104"></a> nsIRDFContainer</h3>
<H4><A NAME="77105"></A> Adding an element to a container</H4>    <p>This interface <!--INDEX nsIRDFContainer interface --> 
<P>You can add an <!--INDEX containers:elements, adding -->  <!--INDEX elements:containers, adding to -->  element to a container in two ways. You can append it to the end of the list with <TT>Append</TT> or insert it at a specific place in the container:    <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainer -->
<PRE>newLiteral = RDF.GetLiteral('Ian');    <!--INDEX interfaces:RDF:nsIRDFContainer --> provides
     vector-like access to an RDF container's elements.<a name=
     "b291"></a><a href="#291">[*]</a> The <i>nsIRDFContainer</i>
     interface allows you to add, look up, and remove elements from
     a container once you create it.</p>
     <h4><a name="77105"></a> Adding an element to a container</h4>
     <p>You can add an <!--INDEX containers:elements, adding --> 
     <!--INDEX elements:containers, adding to --> element to a
     container in two ways. You can append it to the end of the list
     with <tt>Append</tt> or insert it at a specific place in the
     container:</p>
 <pre>
 newLiteral = RDF.GetLiteral('Ian');
 aSequence.AppendElement(newLiteral);  aSequence.AppendElement(newLiteral);
 // or  // or
aSequence.InsertElementAt(newLiteral,3,true);</PRE>aSequence.InsertElementAt(newLiteral,3,true);
<P>The second attribute in <TT>InsertElementAt</TT> is where the element should be placed. The third attribute specifies that the list can be reordered. This method is useful for working with ordered containers such as sequences. If this locking parameter is set to false and an element already exists at that location, then the existing element is overwritten.</pre>
<H4><A NAME="77106"></A> Removing an element from a container</H4>    <p>The second attribute in <tt>InsertElementAt</tt> is where
<P>Removing an element from a container works much the same as adding one. The difference is that a reordering attribute is included on <TT>RemoveElement</TT>. If this attribute is set to false, you may have holes in the container, which can create problems when enumerating or indexing elements within.    the element should be placed. The third attribute specifies
<PRE>newLiteral = RDF.GetLiteral('Ian');    that the list can be reordered. This method is useful for
     working with ordered containers such as sequences. If this
     locking parameter is set to false and an element already exists
     at that location, then the existing element is overwritten.</p>
     <h4><a name="77106"></a> Removing an element from a
     container</h4>
     <p>Removing an element from a container works much the same as
     adding one. The difference is that a reordering attribute is
     included on <tt>RemoveElement</tt>. If this attribute is set to
     false, you may have holes in the container, which can create
     problems when enumerating or indexing elements within.</p>
 <pre>
 newLiteral = RDF.GetLiteral('Ian');
 aSequence.RemoveElement(newLiteral,true);  aSequence.RemoveElement(newLiteral,true);
 // or  // or
aSequence.RemoveElementAt(newLiteral,3,true);</PRE>aSequence.RemoveElementAt(newLiteral,3,true);
<P>If you use the <TT>indexOf</TT> property of <TT>nsIRDFContainer</TT>, you can also use <TT>GetCount</TT> to learn how many elements are in the container. The count starts at 0 when the container is initialized:</pre>
<PRE>numberOfElements = aSequence.GetCount( );</PRE>    <p>If you use the <tt>indexOf</tt> property of
<P>Once you have the sequence, the datasource and resource the sequence resides in can be retrieved. In effect, these properties look outward instead of toward the data:    <tt>nsIRDFContainer</tt>, you can also use <tt>GetCount</tt> to
<PRE>seqDatasource = aSequence.DataSource;    learn how many elements are in the container. The count starts
seqResource = aSequence.Resource;</PRE>    at 0 when the container is initialized:</p>
<P>Like many methods in the RDF interfaces, this one allows you to traverse and retrieve any part of the RDF graph.<pre>
<H3><A NAME="77107"></A> nsIRDFXML Interfaces</H3>numberOfElements = aSequence.GetCount( );
<P>The RDF/XML interfaces are covered only briefly here. Besides being abstract and confusing, these interfaces require a lot of error handling to work correctly. Fortunately, a library on mozdev.org called <I>JSLib</I> handles RDF file access. The <I>JSLib</I> XML library does the dirty work in a friendly manner. See the section <A HREF="#77112">"JSLib RDF Files</A>," later in this chapter, for more information.</pre>
<H4><A NAME="77108"></A> nsIRDFXMLParser and nsIRDFXMLSink</H4>    <p>Once you have the sequence, the datasource and resource the
<P><I>nsIRDFXML</I>  <!--INDEX nsIRDFXMLParser interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLParser -->  <!--INDEX interfaces:RDF:nsIRDFXMLParser --> is the raw RDF/XML parser of Mozilla. Used by Mozilla, its main purpose is to parse an RDF file  <!--INDEX parsing:RDF files --> asynchronously as a stream listener. Though this subject is beyond the scope of this book, the interface provides something interesting and useful. The <TT>parseString</TT> function allows you to feed <I>nsIRDFXMLParser</I> a string and have it parse that data as RDF and put it into a datasource, as <A HREF="#77042">Example 10-9</A> demonstrates.    sequence resides in can be retrieved. In effect, these
    properties look outward instead of toward the data:</p>
<P><I>Example 10-9: <A NAME="77042"></A></I><pre>
<I>Parse an RDF/XML string into a datasource</I>seqDatasource = aSequence.DataSource;
<PRE> RDF = Components.classes</TD>['@mozilla.org/rdf/rdf-service;1'].seqResource = aSequence.Resource;
 </pre>
     <p>Like many methods in the RDF interfaces, this one allows you
     to traverse and retrieve any part of the RDF graph.</p>
     <h3><a name="77107"></a> nsIRDFXML Interfaces</h3>
     <p>The RDF/XML interfaces are covered only briefly here.
     Besides being abstract and confusing, these interfaces require
     a lot of error handling to work correctly. Fortunately, a
     library on mozdev.org called <i>JSLib</i> handles RDF file
     access. The <i>JSLib</i> XML library does the dirty work in a
     friendly manner. See the section <a href="#77112">"JSLib RDF
     Files</a>," later in this chapter, for more information.</p>
     <h4><a name="77108"></a> nsIRDFXMLParser and nsIRDFXMLSink</h4>
     <p><i>nsIRDFXML</i> <!--INDEX nsIRDFXMLParser interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLParser -->
     <!--INDEX interfaces:RDF:nsIRDFXMLParser --> is the raw RDF/XML
     parser of Mozilla. Used by Mozilla, its main purpose is to
     parse an RDF file <!--INDEX parsing:RDF files -->
     asynchronously as a stream listener. Though this subject is
     beyond the scope of this book, the interface provides something
     interesting and useful. The <tt>parseString</tt> function
     allows you to feed <i>nsIRDFXMLParser</i> a string and have it
     parse that data as RDF and put it into a datasource, as <a
     href="#77042">Example 10-9</a> demonstrates.</p>
     <p><i>Example 10-9: <a name="77042"></a></i> <i>Parse an
     RDF/XML string into a datasource</i></p>
 <pre>
  RDF = Components.classes&lt;/td&gt;['@mozilla.org/rdf/rdf-service;1'].
          getService(Components.interfaces.nsIRDFService);           getService(Components.interfaces.nsIRDFService);
  // Used to create a URI below   // Used to create a URI below
 ios = Components.classes</TD>["@mozilla.org/network/io-service;1"]. ios = Components.classes&lt;/td&gt;["@mozilla.org/network/io-service;1"].
        getService(Components.interfaces.nsIIOService);         getService(Components.interfaces.nsIIOService);
  xmlParser = '@mozilla.org/rdf/xml-parser;1';   xmlParser = '@mozilla.org/rdf/xml-parser;1';
 parser = Components.classes</TD>[xmlParser]. parser = Components.classes&lt;/td&gt;[xmlParser].
           createInstance(Components.interfaces.nsIRDFXMLParser);            createInstance(Components.interfaces.nsIRDFXMLParser);
 uri = ios.newURI("<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#", null); uri = ios.newURI("<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#", null);
  // Entire RDF File stored in a string   // Entire RDF File stored in a string
  rdfString =   rdfString =
   '&lt;rdf:RDF xmlns:rdf=</TD><I><A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#</I>' +   '&lt;rdf:RDF xmlns:rdf=&lt;/td&gt;<i><a href=
   'xmlns:b="<A HREF="http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</A>#"&gt;' +"http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#</i>' +
    'xmlns:b="<a href=
 "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#"&gt;' +
    '&lt;rdf:Description about="urn:root"&gt;' + // Rest of file ...     '&lt;rdf:Description about="urn:root"&gt;' + // Rest of file ...
  parser.parseString(datasource,uri,rdfString);   parser.parseString(datasource,uri,rdfString);
 // Parsed string data now resides in the datasource</PRE> // Parsed string data now resides in the datasource
</pre>
<P>The RDF/XML data that was in the string is a part of the datasource and ready for use (just like any other RDF data in a datasource). The <TT>uri</TT> acts as a base reference for the RDF in case of relative links.    <p>The RDF/XML data that was in the string is a part of the
<P><I>nsIRDFXMLParser</I> uses <I>nsIRDFXMLSink</I>  <!--INDEX nsIRDFXMLSink interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSink -->  <!--INDEX interfaces:RDF:nsIRDFXMLsink --> for event  <!--INDEX event handling:RDF files --> handling. The interfaces are totally separate, but behind the scenes, they work together with the incoming data. <A HREF="#77044">Example 10-10</A> shows how a series of events is created in an object and then used to handle parser events.    datasource and ready for use (just like any other RDF data in a
    datasource). The <tt>uri</tt> acts as a base reference for the
Example 10-10<A NAME="77044"></A>    RDF in case of relative links.</p>
<I>Setup nsIRDFXMLSink with event handlers</I>    <p><i>nsIRDFXMLParser</i> uses <i>nsIRDFXMLSink</i> 
<PRE> var Observer = {    <!--INDEX nsIRDFXMLSink interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSink -->
     <!--INDEX interfaces:RDF:nsIRDFXMLsink --> for event 
     <!--INDEX event handling:RDF files --> handling. The interfaces
     are totally separate, but behind the scenes, they work together
     with the incoming data. <a href="#77044">Example 10-10</a>
     shows how a series of events is created in an object and then
     used to handle parser events. Example 10-10<a name="77044"></a>
     <i>Setup nsIRDFXMLSink with event handlers</i></p>
 <pre>
  var Observer = {
     onBeginLoad: function(aSink)      onBeginLoad: function(aSink)
     {      {
       alert("Beginning to load the RDF/XML...");        alert("Beginning to load the RDF/XML...");
Line 703  Example 10-10<A NAME="77044"></A> Line 1730  Example 10-10<A NAME="77044"></A>
    {     {
      alert("Error: " + aErrorMsg);       alert("Error: " + aErrorMsg);
    }     }
 };</PRE> };
</pre>
<P>Once the event handlers are set up, you can use <I>nsIRDFXMLSink</I>:    <p>Once the event handlers are set up, you can use
<PRE>sink = datasource.QueryInterface(Components.interfaces.nsIRDFXMLSink);    <i>nsIRDFXMLSink</i>:</p>
sink.addXMLSinkObserver(observer);</PRE><pre>
<P>The events are then triggered automatically when the datasource is loaded up with data, allowing you to create handlers that manipulate the data as it appears.sink = datasource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
<H4><A NAME="77109"></A> nsIRDFXMLSerializer and nsIRDFXMLSource</H4>sink.addXMLSinkObserver(observer);
<P>These two <!--INDEX nsIRDFXMLSerializer interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSerializer -->  <!--INDEX interfaces:RDF:nsIRDFXMLSerializer -->  interfaces are meant to work together. <I>nsIRDFXMLSerializer</I> lets you <TT>init</TT> a datasource into the <TT>xml-serializer</TT> module that outputs RDF. However, <I> <!--INDEX nsIRDFXMLSource interface -->  <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSource -->  <!--INDEX interfaces:RDF:nsIRDFXMLSource --> nsIRDFXMLSource</I> actually contains the <TT>Serialize</TT> function. Here's how to serialize a datasource into an alert:</pre>
<PRE>serializer = '@mozilla.org/rdf/xml-serializer;1';    <p>The events are then triggered automatically when the
     datasource is loaded up with data, allowing you to create
     handlers that manipulate the data as it appears.</p>
     <h4><a name="77109"></a> nsIRDFXMLSerializer and
     nsIRDFXMLSource</h4>
     <p>These two <!--INDEX nsIRDFXMLSerializer interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSerializer -->
     <!--INDEX interfaces:RDF:nsIRDFXMLSerializer --> interfaces are
     meant to work together. <i>nsIRDFXMLSerializer</i> lets you
     <tt>init</tt> a datasource into the <tt>xml-serializer</tt>
     module that outputs RDF. However, <i>
     <!--INDEX nsIRDFXMLSource interface --> 
     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSource -->
     <!--INDEX interfaces:RDF:nsIRDFXMLSource -->
     nsIRDFXMLSource</i> actually contains the <tt>Serialize</tt>
     function. Here's how to serialize a datasource into an
     alert:</p>
 <pre>
 serializer = '@mozilla.org/rdf/xml-serializer;1';
 s = Components.classes[serializer].  s = Components.classes[serializer].
 createInstance(Components.interfaces.nsIRDFXMLSerializer);  createInstance(Components.interfaces.nsIRDFXMLSerializer);
 s.init(datasource);  s.init(datasource);
Line 721  output.write = new function(buf,count) Line 1766  output.write = new function(buf,count)
 alert(buf); // Show the serialized syntax  alert(buf); // Show the serialized syntax
 return count;  return count;
 }  }
s.QueryInterface(Components.interfaces.nsIRDFXMLSource).Serialize(output);</PRE>s.QueryInterface(Components.interfaces.nsIRDFXMLSource).Serialize(output);
<P>As in the previous example with <I>nsIRDFXMLParser</I>, <A HREF="#77044">Example 10-10</A> does not use RDF data from a file. The serialized data is passed directly to an alert, which then displays the generated RDF.</pre>
<H2><A NAME="77110"></A> Template Dynamics</H2>    <p>As in the previous example with <i>nsIRDFXMLParser</i>, <a
<P>Once you learn how to create templates and modify datasources, the ultimate in template mastery is to apply datasources to a template dynamically.    href="#77044">Example 10-10</a> does not use RDF data from a
<P>This process is done through the <TT>database</TT> property of a XUL element that contains a template. The object returned by this property has only two methods, <TT>AddDataSource</TT> and <TT>RemoveDataSource</TT>. A separate <TT>builder.rebuild</TT> function is also available for refreshing the template's display, but you probably won't need it once the template automatically updates itself. The addition and removal of a datasource to a <TT>&lt;tree&gt;</TT> template is demonstrated here:    file. The serialized data is passed directly to an alert, which
<PRE>tree = document.getElementById('tree-template');    then displays the generated RDF.</p>
     <h2><a name="77110"></a> Template Dynamics</h2>
     <p>Once you learn how to create templates and modify
     datasources, the ultimate in template mastery is to apply
     datasources to a template dynamically.</p>
     <p>This process is done through the <tt>database</tt> property
     of a XUL element that contains a template. The object returned
     by this property has only two methods, <tt>AddDataSource</tt>
     and <tt>RemoveDataSource</tt>. A separate
     <tt>builder.rebuild</tt> function is also available for
     refreshing the template's display, but you probably won't need
     it once the template automatically updates itself. The addition
     and removal of a datasource to a <tt>&lt;tree&gt;</tt> template
     is demonstrated here:</p>
 <pre>
 tree = document.getElementById('tree-template');
 tree.database.AddDataSource(someDatasource);  tree.database.AddDataSource(someDatasource);
 // tree will now update its display to show contents  // tree will now update its display to show contents
 tree.database.RemoveDataSource(someDatasource);  tree.database.RemoveDataSource(someDatasource);
 // tree will now be empty  // tree will now be empty
 // Optional, use only when tree is not updating for some reason  // Optional, use only when tree is not updating for some reason
tree.builder.rebuild( );</PRE>tree.builder.rebuild( );
<P>You can add and remove any datasource as long as the template actually matches the data inside it. Also, multiple datasources can be applied to the same template with no problems, which allows you to aggregate data from different places, such as contact data, work information, and computer hardware information (e.g., "Eric uses a Compaq with the serial number 1223456-1091 to write his book and he sits on the fourth floor of the Acme Building, which is the Bay Area branch of Acme Enterprises.)</pre>
<H3><A NAME="77111"></A> Template Dynamics in XBL</H3>    <p>You can add and remove any datasource as long as the
<P>Putting templates  <!--INDEX XBL (eXtensible Binding Language):templates -->  <!--INDEX templates:XBL -->  <!--INDEX datasources:templates --> inside XBL can be a useful organizational scheme. Here is a basic implementation of a widget that creates a list of people based on names listed in an attribute:    template actually matches the data inside it. Also, multiple
<PRE>&lt;people names="Brian King,Eric Murphy,Ian Oeschger,Pete Collins,David Boswell"/&gt;</PRE>    datasources can be applied to the same template with no
<P>Obviously, the comma is used as the delimiter for this list. The constructor element in <A HREF="#77046">Example 10-11</A> uses JavaScript to break up this string.    problems, which allows you to aggregate data from different
    places, such as contact data, work information, and computer
Example 10-11<A NAME="77046"></A>    hardware information (e.g., "Eric uses a Compaq with the serial
<I>Binding with in-memory datasource and &lt;listbox&gt; template</I>    number 1223456-1091 to write his book and he sits on the fourth
<PRE> &lt;?xml version="1.0"?&gt;    floor of the Acme Building, which is the Bay Area branch of
 &lt;bindings xmlns ="<A HREF="http://www.mozilla.org/xbl">http://www.mozilla.org/xbl</A>"    Acme Enterprises.)</p>
 xmlns:xul="<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"&gt;    <h3><a name="77111"></a> Template Dynamics in XBL</h3>
     <p>Putting templates 
     <!--INDEX XBL (eXtensible Binding Language):templates --> 
     <!--INDEX templates:XBL --> <!--INDEX datasources:templates -->
     inside XBL can be a useful organizational scheme. Here is a
     basic implementation of a widget that creates a list of people
     based on names listed in an attribute:</p>
 <pre>
 &lt;people names="Brian King,Eric Murphy,Ian Oeschger,Pete Collins,David Boswell"/&gt;
 </pre>
     
 <p>Obviously, the comma is used as the delimiter for this list. The constructor 
   element in <a href="#77046">Example 10-11</a> uses JavaScript to break up this 
   string. </p>
 <p>Example 10-11<a name=
     "77046"></a> <i>Binding with in-memory datasource and &lt;listbox&gt; template</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;bindings xmlns ="<a href=
 "http://www.mozilla.org/xbl">http://www.mozilla.org/xbl</a>"
  xmlns:xul="<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
    &lt;binding id="people"&gt;     &lt;binding id="people"&gt;
      &lt;implementation&gt;       &lt;implementation&gt;
        &lt;constructor&gt;         &lt;constructor&gt;
       &lt;!</TD>[CDATA[       &lt;!&lt;/td&gt;[CDATA[
          // Read the Names into an Array           // Read the Names into an Array
         names = document.getAnonymousNodes(this)</TD>[0].getAttribute('names');         names = document.getAnonymousNodes(this)&lt;/td&gt;[0].getAttribute('names');
          names = new String(names);           names = new String(names);
          namesArray= names.split(',');           namesArray= names.split(',');
          // Initialize the RDF Service           // Initialize the RDF Service
          rdf = Components           rdf = Components
              .classes</TD>['@mozilla.org/rdf/rdf-service;1']              .classes&lt;/td&gt;['@mozilla.org/rdf/rdf-service;1']
               .getService(Components.interfaces.nsIRDFService);                .getService(Components.interfaces.nsIRDFService);
          // Initialize a Datasource in Memory           // Initialize a Datasource in Memory
               inMemory = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';                inMemory = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
         datasource = Components.classes</TD>[inMemory].         datasource = Components.classes&lt;/td&gt;[inMemory].
             createInstance(Components.interfaces.nsIRDFDataSource);              createInstance(Components.interfaces.nsIRDFDataSource);
          // Create the Root Node and an Anonymous Resource to Start With           // Create the Root Node and an Anonymous Resource to Start With
          root   = rdf.GetResource('urn:root');           root   = rdf.GetResource('urn:root');
Line 766  Example 10-11<A NAME="77046"></A> Line 1847  Example 10-11<A NAME="77046"></A>
          // Insert the People resource into the RDF graph           // Insert the People resource into the RDF graph
          datasource.Assert           datasource.Assert
            (root,             (root,
            rdf.GetResource('<A HREF="http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</A>#people'),            rdf.GetResource('<a href=
 "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#people'),
             people,true);              people,true);
          // Initialize Methods needed for Containers           // Initialize Methods needed for Containers
          rdfc = Components           rdfc = Components
               .classes</TD>['@mozilla.org/rdf/container-utils;1']               .classes&lt;/td&gt;['@mozilla.org/rdf/container-utils;1']
                .getService(Components.interfaces.nsIRDFContainerUtils);                 .getService(Components.interfaces.nsIRDFContainerUtils);
          // For the People resource, make a Sequence of people           // For the People resource, make a Sequence of people
          peopleSequence = rdfc.MakeSeq(datasource, people);           peopleSequence = rdfc.MakeSeq(datasource, people);
Line 781  Example 10-11<A NAME="77046"></A> Line 1863  Example 10-11<A NAME="77046"></A>
            // Insert the Person's name into the RDF graph underneath number             // Insert the Person's name into the RDF graph underneath number
            datasource.Assert             datasource.Assert
              (person,               (person,
              rdf.GetResource('<A HREF="http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</A>#name'),              rdf.GetResource('<a href=
              rdf.GetLiteral(namesArray</TD>[i]),true);"http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#name'),
               rdf.GetLiteral(namesArray&lt;/td&gt;[i]),true);
            peopleSequence.AppendElement(person);             peopleSequence.AppendElement(person);
          }           }
         list = document.getAnonymousNodes(this)</TD>[1];         list = document.getAnonymousNodes(this)&lt;/td&gt;[1];
          list.database.AddDataSource(datasource);           list.database.AddDataSource(datasource);
        ]]&gt;         ]]&gt;
        &lt;/constructor&gt;         &lt;/constructor&gt;
Line 798  Example 10-11<A NAME="77046"></A> Line 1881  Example 10-11<A NAME="77046"></A>
              &lt;xul:conditions&gt;               &lt;xul:conditions&gt;
                &lt;xul:content uri="?uri"/&gt;                 &lt;xul:content uri="?uri"/&gt;
                &lt;xul:triple subject="?uri"                 &lt;xul:triple subject="?uri"
                        predicate="<A HREF="http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</A>#people"                              object="?people"/&gt;                           predicate="<a href=
 "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#people"
                            object="?people"/&gt;
                &lt;xul:member container="?people" child="?person"/&gt;                 &lt;xul:member container="?people" child="?person"/&gt;
                &lt;xul:triple subject="?person"                 &lt;xul:triple subject="?person"
                        predicate="<A HREF="http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</A>#name"                         object="?name"/&gt;                           predicate="<a href=
 "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#name"
                            object="?name"/&gt;
              &lt;/xul:conditions&gt;               &lt;/xul:conditions&gt;
              &lt;xul:action&gt;               &lt;xul:action&gt;
                &lt;xul:listitem uri="?person"&gt;                 &lt;xul:listitem uri="?person"&gt;
Line 816  Example 10-11<A NAME="77046"></A> Line 1903  Example 10-11<A NAME="77046"></A>
        &lt;/xul&gt;         &lt;/xul&gt;
      &lt;/content&gt;       &lt;/content&gt;
    &lt;/binding&gt;     &lt;/binding&gt;
 &lt;/bindings&gt;</PRE> &lt;/bindings&gt;
</pre>
<P>In <A HREF="#77046">Example 10-11</A>, everything you need to display a datasource dynamically is present. The only difference between this dynamically generated version and a static RDF-based template is the <TT>datasources="rdf:null"</TT>, which specifies that the template does not refer to an actual datasource. Data that is edited, rearranged, or changed in a different way is often displayed dynamically in the UI with templates in this manner.    <p>In <a href="#77046">Example 10-11</a>, everything you need
<H2><A NAME="77112"></A> JSLib RDF Files</H2>    to display a datasource dynamically is present. The only
<P>Working  <!--INDEX STARTRANGE--RDF (Resource Description Framework):files:JSLib -->  <!--INDEX STARTRANGE--JSLib libraries:RDF files -->  <!--INDEX STARTRANGE--files:RDF:JSLib --> with actual RDF files is not easy. However, JSLib (<I><A HREF="http://jslib.mozdev.org">http://jslib.mozdev.org</A></I>) provides an RDF file library that can help you develop an RDF-based application. The library provides many types of error checking, as well as a friendly abstraction away from the RDF/XML interfaces of Mozilla (see <A HREF="#77107">"nsIRDFXML Interfaces</A>," later in this chapter). <A HREF="#77048">Example 10-12</A> shows some common uses of the <TT>RDFFile</TT> class in JSLib. This functionality can be used in situations in which you have data in RDF that you want to pull out "manually" and use piece by piece (rather than as a whole datasource in a template).    difference between this dynamically generated version and a
    static RDF-based template is the
Example 10-12<A NAME="77048"></A>    <tt>datasources="rdf:null"</tt>, which specifies that the
<I>Creating and modifying an RDF file using JSLib</I>    template does not refer to an actual datasource. Data that is
<PRE> var rdfFileURL = 'chrome://jarfly/content/jar.rdf';    edited, rearranged, or changed in a different way is often
     displayed dynamically in the UI with templates in this
     manner.</p>
     <h2><a name="77112"></a> JSLib RDF Files</h2>
     
 <p>Working 
   <!--INDEX STARTRANGE==RDF (Resource Description Framework):files:JSLib -->
   <!--INDEX STARTRANGE==JSLib libraries:RDF files -->
   <!--INDEX STARTRANGE==files:RDF:JSLib -->
   with actual RDF files is not easy. However, JSLib (<i><a href=
     "http://jslib.mozdev.org">http://jslib.mozdev.org</a></i>) provides an RDF 
   file library that can help you develop an RDF-based application. The library 
   provides many types of error checking, as well as a friendly abstraction away 
   from the RDF/XML interfaces of Mozilla (see <a href="#77107">"nsIRDFXML Interfaces</a>," 
   later in this chapter). <a href=
     "#77048">Example 10-12</a> shows some common uses of the <tt>RDFFile</tt> 
   class in JSLib. This functionality can be used in situations in which you have 
   data in RDF that you want to pull out "manually" and use piece by piece (rather 
   than as a whole datasource in a template). </p>
 <p>Example 10-12<a name=
     "77048"></a> <i>Creating and modifying an RDF file using JSLib</i></p>
 <pre>
  var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
  var gTreeBody = null;   var gTreeBody = null;
  var gListbox = null;   var gListbox = null;
  var gRDF = null;   var gRDF = null;
Line 836  Example 10-12<A NAME="77048"></A> Line 1945  Example 10-12<A NAME="77048"></A>
      path = path.replace(/\//g,"\\");       path = path.replace(/\//g,"\\");
      // Only needed on Windows, until JSLib is fixed       // Only needed on Windows, until JSLib is fixed
    }     }
   gRDF = new RDFFile(path,'jar:flies','<A HREF="http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</A>#');   gRDF = new RDFFile(path,'jar:flies','<a href=
 "http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</a>#');
    gTreeBody = document.getElementById('tb');     gTreeBody = document.getElementById('tb');
    gTreeBody.database.AddDataSource(gRDF.dsource);     gTreeBody.database.AddDataSource(gRDF.dsource);
    gListbox  = document.getElementById('list');     gListbox  = document.getElementById('list');
Line 916  Example 10-12<A NAME="77048"></A> Line 2026  Example 10-12<A NAME="77048"></A>
  function changeQ(quantity)   function changeQ(quantity)
  {   {
    document.getElementById('quantityField').value=quantity;     document.getElementById('quantityField').value=quantity;
 }</PRE> }
</pre>
<P>This example contains a datasource that represents a collection of flies. These flies are built up dynamically with JavaScript objects from the RDF library, which represent the datasource itself (<TT>gRDF = new RDFFile</TT>), methods that view and update the data (<TT>if(gRDF.getAttribute(tempItem,'name')==name</TT>), and utilities that make work with RDF files easier (<TT>path = fileUtils.chrome_to_path(rdfFileURL)</TT>).    <p>This example contains a datasource that represents a
<P><A HREF="#77050">Example 10-13</A> initializes and updates a file after it changes.    collection of flies. These flies are built up dynamically with
    JavaScript objects from the RDF library, which represent the
Example 10-13<A NAME="77050"></A>    datasource itself (<tt>gRDF = new RDFFile</tt>), methods that
<I>Initialization</I>    view and update the data
<PRE> var rdfFileURL = 'chrome://jarfly/content/jar.rdf';    (<tt>if(gRDF.getAttribute(tempItem,'name')==name</tt>), and
     utilities that make work with RDF files easier (<tt>path =
     fileUtils.chrome_to_path(rdfFileURL)</tt>).</p>
     <p><a href="#77050">Example 10-13</a> initializes and updates a
     file after it changes. Example 10-13<a name="77050"></a>
     <i>Initialization</i></p>
 <pre>
  var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
  var gTreeBody = null;   var gTreeBody = null;
  var gListbox = null;   var gListbox = null;
  var gRDF = null;   var gRDF = null;
Line 935  Example 10-13<A NAME="77050"></A> Line 2052  Example 10-13<A NAME="77050"></A>
      path = path.replace(/\//g,"\\");       path = path.replace(/\//g,"\\");
      // Only needed on Windows, until JSLib is fixed       // Only needed on Windows, until JSLib is fixed
    }     }
   gRDF = new RDFFile(path,'jar:flies','<A HREF="http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</A>#');</PRE>   gRDF = new RDFFile(path,'jar:flies','<a href=
"http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</a>#');
<P>In <A HREF="#77050">Example 10-13</A>, the file URL is set to an RDF file in the chrome area. Note that both a <TT>&lt;tree&gt;</TT> and a <TT>&lt;listbox&gt;</TT>, which display the same data in different ways, will be updated with the same datasource. The <TT>onload</TT> function is called after the main XUL document is loaded. A class called <TT>FileUtils</TT> is initialized, which will create a path to the RDF file. If the file doesn't already exist, JSLib automatically creates it.</pre>
<P>Finally, the <TT>RDFFile</TT> is created by using the path and a root resource identifier, and the "xFly" namespace is used for the data references. <A HREF="#77052">Example 10-14</A> shows that the RDF file is ready to have its data added and deleted.    <p>In <a href="#77050">Example 10-13</a>, the file URL is set
    to an RDF file in the chrome area. Note that both a
Example 10-14<A NAME="77052"></A>    <tt>&lt;tree&gt;</tt> and a <tt>&lt;listbox&gt;</tt>, which
<I>Data updating</I>    display the same data in different ways, will be updated with
<PRE> function update( )    the same datasource. The <tt>onload</tt> function is called
     after the main XUL document is loaded. A class called
     <tt>FileUtils</tt> is initialized, which will create a path to
     the RDF file. If the file doesn't already exist, JSLib
     automatically creates it.</p>
     
 <p>Finally, the <tt>RDFFile</tt> is created by using the path and a root resource 
   identifier, and the "xFly" namespace is used for the data references. <a href="#77052">Example 
   10-14</a> shows that the RDF file is ready to have its data added and deleted. 
 </p>
 <p>Example 10-14<a name="77052"></a> <i>Data updating</i></p>
 <pre>
  function update( )
  {   {
    ...     ...
    var seqLength = 0;     var seqLength = 0;
    if(gRDF.doesSeqExist('types'))     if(gRDF.doesSeqExist('types'))
    {     {
      seqLength = gRDF.getSeqSubNodes('types').length;       seqLength = gRDF.getSeqSubNodes('types').length;
     //if(del)gRDF.removeSeq('types',false);
    }     }
    else     else
      gRDF.addSeq('types');       gRDF.addSeq('types');
Line 982  Example 10-14<A NAME="77052"></A> Line 2111  Example 10-14<A NAME="77052"></A>
    else     else
      gRDF.removeNode(item);       gRDF.removeNode(item);
    gRDF.flush( );     gRDF.flush( );
   onload( );</PRE>   onload( );
</pre>
<P><A HREF="#77052">Example 10-14</A> contains a modified version of the <TT>update</TT> function. First, the function checks to see if a sequence called <TT>types</TT> is in the RDF file. If not, it creates one. Next, it appends an item to the sequence using <TT>type:_+(seqLength+1)</TT>. The same type of container setup was described in the section <A HREF="#77104">"nsIRDFContainer</A>," earlier in this chapter.    <p><a href="#77052">Example 10-14</a> contains a modified
<P>The <TT>update</TT> function then adds the color, quantity, and "dead" properties of that new item in the sequence. Next, it ensures that you actually want to add the item to the RDF file and flushes it out if not. It then recalls the <TT>onload</TT> function to update the template display.    version of the <tt>update</tt> function. First, the function
<P>These are the basics of using <TT>RDFFile</TT>. As you can see, using JSLib for RDF is often much easier than trying to implement a similar setup on your own. More information about <TT>RDFFile</TT> and the other JSLib libraries can  <!--INDEX web sites:JSLib --> be <!--INDEX ENDRANGE--RDF (Resource Description Framework):files:JSLib -->  <!--INDEX ENDRANGE--JSLib libraries:RDF files -->  <!--INDEX ENDRANGE--files:RDF:JSLib -->  found at <I><A HREF="http://www.jslib.mozdev.org/">http://www.jslib.mozdev.org/</A></I>.    checks to see if a sequence called <tt>types</tt> is in the RDF
<H2><A NAME="77113"></A> Manifests</H2>    file. If not, it creates one. Next, it appends an item to the
<P>The package  <!--INDEX RDF (Resource Description Framework):manifest files -->  <!--INDEX manifests:RDF --> descriptions, generally called <I>manifests</I>, use RDF to describe new packages and files to Mozilla. They can be added seamlessly because RDF provides a platform-like environment that facilitates the installation and use of new Mozilla software.    sequence using <tt>type:_+(seqLength+1)</tt>. The same type of
<P>All packages, including the ones that come preinstalled with Mozilla (such as the browser, the MailNews component, and the en-US language pack), have manifests describing them in terms of their relation to other packages. The manifests are typically files called <I>contents.rdf</I>, but they may also be called <I>manifest.rdf</I>. <A HREF="#77054">Example 10-15</A> presents a <I>contents.rdf</I> file that describes a new skin for Mozilla.    container setup was described in the section <a href=
    "#77104">"nsIRDFContainer</a>," earlier in this chapter.</p>
Example 10-15<A NAME="77054"></A>    <p>The <tt>update</tt> function then adds the color, quantity,
<I>Skin manifest</I>    and "dead" properties of that new item in the sequence. Next,
<PRE> &lt;?xml version="1.0"?&gt;    it ensures that you actually want to add the item to the RDF
 &lt;RDF:RDF xmlns:RDF="</TD><I><A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#</I>"    file and flushes it out if not. It then recalls the
   xmlns:chrome="</TD><I><A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#</I>"&gt;    <tt>onload</tt> function to update the template display.</p>
     <p>These are the basics of using <tt>RDFFile</tt>. As you can
     see, using JSLib for RDF is often much easier than trying to
     implement a similar setup on your own. More information about
     <tt>RDFFile</tt> and the other JSLib libraries can 
     <!--INDEX web sites:JSLib --> be 
     <!--INDEX ENDRANGE==RDF (Resource Description Framework):files:JSLib -->
     <!--INDEX ENDRANGE==JSLib libraries:RDF files --> 
     <!--INDEX ENDRANGE==files:RDF:JSLib --> found at <i><a href=
     "http://jslib.mozdev.org/">http://jslib.mozdev.org/</a></i>.</p>
     <h2><a name="77113"></a> Manifests</h2>
     <p>The package 
     <!--INDEX RDF (Resource Description Framework):manifest files -->
     <!--INDEX manifests:RDF --> descriptions, generally called
     <i>manifests</i>, use RDF to describe new packages and files to
     Mozilla. They can be added seamlessly because RDF provides a
     platform-like environment that facilitates the installation and
     use of new Mozilla software.</p>
     
 <p>All packages, including the ones that come preinstalled with Mozilla (such 
   as the browser, the MailNews component, and the en-US language pack), have manifests 
   describing them in terms of their relation to other packages. The manifests 
   are typically files called <i>contents.rdf</i>, but they may also be called 
   <i>manifest.rdf</i>. <a href="#77054">Example 10-15</a> presents a <i>contents.rdf</i> 
   file that describes a new skin for Mozilla. </p>
 <p>Example 10-15<a name="77054"></a> <i>Skin manifest</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="&lt;/td&gt;<i><a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#</i>"
    xmlns:chrome="&lt;/td&gt;<i><a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#</i>"&gt;
  &lt;!-- List all the skins being supplied by this theme --&gt;   &lt;!-- List all the skins being supplied by this theme --&gt;
  &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;   &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
    &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;     &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;
Line 1003  Example 10-15<A NAME="77054"></A> Line 2163  Example 10-15<A NAME="77054"></A>
  &lt;!-- Modern Information --&gt;   &lt;!-- Modern Information --&gt;
  &lt;RDF:Description about="urn:mozilla:skin:modern/1.0"   &lt;RDF:Description about="urn:mozilla:skin:modern/1.0"
    chrome:displayName="Modern"     chrome:displayName="Modern"
   chrome:author="</TD><I><A HREF="MAILTO:themes@mozilla.org">themes@mozilla.org</A></I>"   chrome:author="&lt;/td&gt;<i><a href=
   chrome:name="</TD><I><A HREF="MAILTO:themes@mozilla.org/modern/1.0">themes@mozilla.org/modern/1.0</A></I>"&gt;"MAILTO:themes@mozilla.org">themes@mozilla.org</a></i>"
    chrome:name="&lt;/td&gt;<i><a href=
 "MAILTO:themes@mozilla.org/modern/1.0">themes@mozilla.org/modern/1.0</a></i>"&gt;
  &lt;chrome:packages&gt;   &lt;chrome:packages&gt;
    &lt;RDF:Seq about="urn:mozilla:skin:modern/1.0:packages"&gt;     &lt;RDF:Seq about="urn:mozilla:skin:modern/1.0:packages"&gt;
      &lt;--RDF:li resource="urn:mozilla:skin:modern/1.0:aim"/ --&gt;       &lt;--RDF:li resource="urn:mozilla:skin:modern/1.0:aim"/ --&gt;
Line 1016  Example 10-15<A NAME="77054"></A> Line 2178  Example 10-15<A NAME="77054"></A>
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
  &lt;/chrome:packages&gt;   &lt;/chrome:packages&gt;
  &lt;/RDF:Description&gt;   &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>As you can see, the manifest is divided up into sections. After the preamble, where the XML processing instruction and the namespace declarations are made, an RDF sequence lists all the themes defined or supplemented (since you can create a package updated for only one Mozilla component, such as the browser) by this package. This section contains only one <TT>RDF:li-</TT>the modern theme.    <p>As you can see, the manifest is divided up into sections.
<P>The next section gives more information on the theme, such as the author, the theme name, and a description. The <TT>chrome:packages</TT> structure that completes the manifest describes the packages to which this theme should be applied. All major components of the Netscape browser are listed in this example-including the AIM client that is not a part of Mozilla-but is skinned by themes such as Modern.    After the preamble, where the XML processing instruction and
<H3><A NAME="77114"></A> RDF and Dynamic Overlays</H3>    the namespace declarations are made, an RDF sequence lists all
<P>Manifests can <!--INDEX dynamic overlays:RDF -->  <!--INDEX overlays:RDF -->  <!--INDEX RDF (Resource Description Framework):manifest files:dynamic overalys and -->  <!--INDEX manifests:RDF:dynamic overlays and -->  also add new menu items to existing Mozilla menus. When you add a new package to Mozilla, you should make it accessible from within the browser application, where users can access it easily. This is where RDF and dynamic overlays come in.    the themes defined or supplemented (since you can create a
<P>The RDF you provide in your package makes it possible for the chrome registry, discussed in <A HREF="ch06.html#77063">Chapter 6</A>, to find,     package updated for only one Mozilla component, such as the
understand, and register your new files. Packages must be registered if they are to be skinned, localized, or accessed using the special tools Mozilla provides (e.g., the chrome URL or XPConnect to the XPCOM libraries). If you do not register your package by providing the necessary RDF manifests, it cannot be accessed except as a disparate collection of files in the browser's main content window, which is not what you want.    browser) by this package. This section contains only one
<P>You can add overlays in Mozilla in two ways: import them explicitly by using an overlay processing instruction at the top of the XUL file into which items in the overlay file are to be "composed," or use RDF to register and load overlay files at runtime. This latter method will be used here to add an "xFly" item to the Tools menu of the Mozilla suite of applications.    <tt>RDF:li-</tt>the modern theme.</p>
<P><A HREF="#77056">Example 10-16</A> shows the <I>contents.rdf</I> manifest format that alerts Mozilla of the presence of an overlay, its target in the Mozilla application, and the package of which it is a part.    <p>The next section gives more information on the theme, such
    as the author, the theme name, and a description. The
Example 10-16<A NAME="77056"></A>    <tt>chrome:packages</tt> structure that completes the manifest
<I>Overlay for a sample application menu</I>    describes the packages to which this theme should be applied.
<PRE> &lt;?xml version="1.0"?&gt;    All major components of the Netscape browser are listed in this
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    example-including the AIM client that is not a part of
          xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;    Mozilla-but is skinned by themes such as Modern.</p>
     <h3><a name="77114"></a> RDF and Dynamic Overlays</h3>
     <p>Manifests can <!--INDEX dynamic overlays:RDF --> 
     <!--INDEX overlays:RDF --> 
     <!--INDEX RDF (Resource Description Framework):manifest files:dynamic overalys and -->
     <!--INDEX manifests:RDF:dynamic overlays and --> also add new
     menu items to existing Mozilla menus. When you add a new
     package to Mozilla, you should make it accessible from within
     the browser application, where users can access it easily. This
     is where RDF and dynamic overlays come in.</p>
     <p>The RDF you provide in your package makes it possible for
     the chrome registry, discussed in <a href=
     "ch06.html#77063">Chapter 6</a>, to find, understand, and
     register your new files. Packages must be registered if they
     are to be skinned, localized, or accessed using the special
     tools Mozilla provides (e.g., the chrome URL or XPConnect to
     the XPCOM libraries). If you do not register your package by
     providing the necessary RDF manifests, it cannot be accessed
     except as a disparate collection of files in the browser's main
     content window, which is not what you want.</p>
     <p>You can add overlays in Mozilla in two ways: import them
     explicitly by using an overlay processing instruction at the
     top of the XUL file into which items in the overlay file are to
     be "composed," or use RDF to register and load overlay files at
     runtime. This latter method will be used here to add an "xFly"
     item to the Tools menu of the Mozilla suite of
     applications.</p>
     
 <p><a href="#77056">Example 10-16</a> shows the <i>contents.rdf</i> manifest format 
   that alerts Mozilla of the presence of an overlay, its target in the Mozilla 
   application, and the package of which it is a part. </p>
 <p>Example 10-16<a name=
     "77056"></a> <i>Overlay for a sample application menu</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
           xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
    &lt;RDF:Seq about="urn:mozilla:package:root"&gt;     &lt;RDF:Seq about="urn:mozilla:package:root"&gt;
      &lt;RDF:li resource="urn:mozilla:package:help"/&gt;       &lt;RDF:li resource="urn:mozilla:package:help"/&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
Line 1044  Example 10-16<A NAME="77056"></A> Line 2244  Example 10-16<A NAME="77056"></A>
    &lt;RDF:Seq about="urn:mozilla:overlays"&gt;     &lt;RDF:Seq about="urn:mozilla:overlays"&gt;
      &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;       &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
   </TD>&lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;   &lt;/td&gt;&lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;
      &lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;       &lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>The manifest in <A HREF="#77056">Example 10-16</A> names the file <I>xflyOverlay.xul</I> as an overlay. Then it names <I>tasksOverlay.xul</I>     <p>The manifest in <a href="#77056">Example 10-16</a> names the
as the base file into which the contents are placed. In this case, the overlays can overlay other overlay files arbitrarily. An overlay can define new content anywhere in the application. Overlays are often responsible for putting new items in menus. As long as the target and overlay <TT>id</TT>s match, any two RDF datasources are merged. You can try this example by putting a single new menu item in an overlay structure like the one shown in <A HREF="#77058">Example 10-17</A>. Save it as <I>xflyOverlay.xul</I> in the <I>xfly</I> content subdirectory and use the manifest information in <A HREF="#77056">Example 10-16</A> as part of the packaging process described in <A HREF="ch06.html#77063">Chapter 6</A>.    file <i>xflyOverlay.xul</i> as an overlay. Then it names
    <i>tasksOverlay.xul</i> as the base file into which the
Example 10-17<A NAME="77058"></A>    contents are placed. In this case, the overlays can overlay
<I>Overlay for an xFly menu item in the browser</I>    other overlay files arbitrarily. An overlay can define new
<PRE> &lt;?xml version="1.0"?&gt;    content anywhere in the application. Overlays are often
     responsible for putting new items in menus. As long as the
     target and overlay <tt>id</tt>s match, any two RDF datasources
     are merged. You can try this example by putting a single new
     menu item in an overlay structure like the one shown in <a
     href="#77058">Example 10-17</a>. Save it as
     <i>xflyOverlay.xul</i> in the <i>xfly</i> content subdirectory
     and use the manifest information in <a href="#77056">Example
     10-16</a> as part of the packaging process described in <a
     href="ch06.html#77063">Chapter 6</a>. Example 10-17<a name=
     "77058"></a> <i>Overlay for an xFly menu item in the
     browser</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;overlay id="xflyMenuID"   &lt;overlay id="xflyMenuID"
         xmlns:html="<A HREF="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</A>"         xmlns:html="<a href=
         xmlns="<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"&gt;"http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
         xmlns="<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
    &lt;menupopup id="tools_menu"&gt;     &lt;menupopup id="tools_menu"&gt;
      &lt;menuitem label="xfly xml editor"       &lt;menuitem label="xfly xml editor"
          oncommand="toOpenWindowByType('mozilla:xfly, 'chrome://xfly/content/');" /&gt;           oncommand="toOpenWindowByType('mozilla:xfly, 'chrome://xfly/content/');" /&gt;
   
  &lt;/menupopup&gt;   &lt;/menupopup&gt;
 &lt;/overlay&gt;
 &lt;/overlay&gt;</PRE></pre>
    <p>The <tt>menupopup</tt> in Mozilla with the ID "tools_menu"
<P>The <TT>menupopup</TT> in Mozilla with the ID "tools_menu" gets a new menu item when this overlay is processed and its content included.    gets a new menu item when this overlay is processed and its
<HR>    content included.</p>
<HR><A NAME="291"></A><A HREF="#b291">[Back]</A>    <hr>
<A NAME="77060"></A>    <hr>
A vector, for those who don't know, is a flexible and    <a name="291"></a><a href="#b291">[Back]</a> <a name=
more accessible version of the array data structure.    "77060"></a> A vector, for those who don't know, is a flexible
<HR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>    and more accessible version of the array data structure. 
<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR></BODY>    <hr>
</HTML>    <br>
     <br>
     File a <a href=
     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
     for chapter 10. <!-- ?php require(NOTES); ? -->
     <?php $hide_text_control=1; $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch10'; require(NOTES); ?>

Removed from v.1.2  
changed lines
  Added in v.1.14


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>