Annotation of books/www/chapters/ch10.html, revision 1.9

1.9     ! petejc      1:     <style type="text/css">
        !             2:       div.c22 {text-align: center}
        !             3:       div.c21 {font-weight: bold; text-align: center}
        !             4:     </style>
        !             5: 
        !             6:     <h2>Chapter 10</h2>
        !             7:     <h1><a name="77061"></a> RDF, RDF Tools, and the Content
        !             8:     Model</h1>
        !             9:     <p><a href="ch09.html#77034">Chapter 9</a> introduced the
        !            10:     Resource Description Framework (RDF) as the basis for building
        !            11:     display data in the interface, where XUL templates take
        !            12:     RDF-based data and transform it into regular widgets. But RDF
        !            13:     is used in many other more subtle ways in Mozilla. In fact, it
        !            14:     is the technology Mozilla uses for much of its own internal
        !            15:     data handling and manipulation.</p>
        !            16:     <p>RDF is, as its name suggests, a framework for integrating
        !            17:     many types of data that go into the browser, including
        !            18:     bookmarks, mail messages, user profiles, IRC channels, new
        !            19:     Mozilla applications, and your collection of sidebar tabs. All
        !            20:     these items are sets of data that RDF represents and
        !            21:     incorporates into the browser consistently. RDF is used
        !            22:     prolifically in Mozilla, which is why this chapter is so
        !            23:     dense.</p>
        !            24:     <p>This chapter introduces RDF, provides some detail about how
        !            25:     Mozilla uses RDF for its own purposes, and describes the RDF
        !            26:     tools that are available on the Mozilla platform. The chapter
        !            27:     includes information on special JavaScript libraries that make
        !            28:     RDF processing much easier, and on the use of RDF in manifests
        !            29:     to represent JAR file contents and cross-platform installation
        !            30:     archives to Mozilla.</p>
        !            31:     <p>Once you understand the concepts in this chapter, you can
        !            32:     make better use of data and metadata in your own application
        !            33:     development.</p>
        !            34:     <h2><a name="77062"></a> RDF Basics</h2>
        !            35:     <p>RDF has two 
        !            36:     <!--INDEX RDF (Resource Description Framework):overview -->
        !            37:     parts: the <i>RDF Data Model</i> and the <i>RDF Syntax</i> (or
        !            38:     Grammar). The RDF Data Model is a graph with nodes and arcs,
        !            39:     much like other data graphs. More specifically, it's a
        !            40:     <i>labeled-directed</i> graph. All nodes and arcs have some
        !            41:     type of label (i.e., an identifier) on them, and arcs point
        !            42:     only in one direction.</p>
        !            43:     <p>The RDF Syntax determines how the RDF Data Model is
        !            44:     represented, typically as a special kind of XML. Most XML
        !            45:     specifications define data in a tree-like model, such as XUL
        !            46:     and XBL. But the RDF Data Model cannot be represented in a true
        !            47:     tree-like structure, so the RDF/XML syntax includes properties
        !            48:     that allow you to represent the same data in more than one way:
        !            49:     elements can appear in different orders but mean the same
        !            50:     thing, the same data can be represented as a child element or
        !            51:     as a parent attribute, and data have indirect meanings. The
        !            52:     meaning is not inherent in the structure of the RDF/XML itself;
        !            53:     only the relationships are inherent. Thus, an RDF processor
        !            54:     must make sense of the represented RDF data. Fortunately, an
        !            55:     excellent RDF processor is integrated into Mozilla.</p>
        !            56:     <h3><a name="77063"></a> RDF Data Model</h3>
        !            57:     <p>Three 
        !            58:     <!--INDEX RDF (Resource Description Framework):data model --> 
        !            59:     <!--INDEX data model (RDF) --> different types of RDF objects
        !            60:     are the basis for all other RDF concepts: <i>resources</i>,
        !            61:     <i>properties</i>, and <i>statements</i>. Resources 
        !            62:     <!--INDEX resources:RDF --> are any type of data described by
        !            63:     RDF. Just as an English sentence is comprised of subjects and
        !            64:     objects, the resources described in RDF are typically subjects
        !            65:     and objects of RDF statements. Consider this example:</p>
        !            66:     <blockquote>
        !            67:       Eric wrote a book.
        !            68:     </blockquote>
        !            69:     <p><i>Eric</i> is the subject of this statement, and would
        !            70:     probably be an RDF resource in an RDF statement. <i>A book</i>,
        !            71:     the object, might also be a resource because it represents
        !            72:     something about which we might want to say more in RDF-for
        !            73:     example, the book is a computer book or the book sells for
        !            74:     twenty dollars. A property <!--INDEX properties:RDF --> is a
        !            75:     characteristic of a resource and might have a relationship to
        !            76:     other resources. In the example, the book was written by Eric.
        !            77:     In the context of RDF, <i>wrote</i> is a property of the
        !            78:     <i>Eric</i> resource. An RDF statement is a resource, a
        !            79:     property, and another resource grouped together. Our example,
        !            80:     made into an RDF statement, might look like this:</p>
        !            81:     <blockquote>
        !            82:       (Eric) wrote (a book)
        !            83:     </blockquote>
        !            84:     <p>Joining RDF statements makes an entire RDF graph.</p>
        !            85:     <blockquote>
        !            86:       <div class="c21">
        !            87:         NOTE
        !            88:       </div>
        !            89:       <p>We are describing the RDF data model here, not the RDF
        !            90:       syntax. The RDF syntax uses XML to describe RDF statements
        !            91:       and the relationship of resources.</p>
        !            92:     </blockquote>
        !            93:     <p>As mentioned in the introduction, the RDF content model is a
        !            94:     <i><!--INDEX labeled-directed graphs (RDF) -->
        !            95:     labeled-directed</i> graph, which means that all relationships
        !            96:     expressed in the graph are unidirectional, as displayed in <a
        !            97:     href="#77002">Figure 10-1</a>.</p>
        !            98:     <div class="c22">
        !            99:       <img src="foo.gif">
        !           100:     </div>
        !           101:     <p><i>Figure 10-1: <a name="77002"></a></i> <i>Simple
        !           102:     labeled-directed graph</i></p>
        !           103:     <p>A resource can contain either a URI or a literal. The root
        !           104:     resource might have a 
        !           105:     <!--INDEX URIs (Universal Resource Identifiers):RDF --> URI,
        !           106:     for example, from which all other resources in the graph
        !           107:     descend. The RDF processor continues from the root resource
        !           108:     along its properties to other resources in the graph until it
        !           109:     runs out of properties to traverse. RDF processing terminates
        !           110:     at a <!--INDEX literals:RDF --> literal, which is just what it
        !           111:     sounds like: something that stands only for itself, generally
        !           112:     represented by a string (e.g., "book," if there were no more
        !           113:     information about the book in the graph). A literal resource
        !           114:     contains only non-RDF data. A literal is a terminal point in
        !           115:     the RDF graph.</p>
        !           116:     <p>For a resource to be labeled, it must be addressed through a
        !           117:     universal resource identifier (URI). This address must be a
        !           118:     unique string that designates what the resource is. In
        !           119:     practice, most resources don't have identifiers because they
        !           120:     are not nodes on the RDF graph that are meant to be accessed
        !           121:     through a URI. <a href="#77004">Figure 10-2</a> is a modified
        !           122:     version of <a href="#77002">Figure 10-1</a> that shows
        !           123:     <i>Eric</i> as a resource identifier and <i>book</i> as a
        !           124:     literal.</p>
        !           125:     <div class="c22">
        !           126:       <img src="foo.gif">
        !           127:     </div>
        !           128:     <p><i>Figure 10-2: <a name="77004"></a></i> <i>Resource to
        !           129:     literal relationship</i></p>
        !           130:     <p>Resources can have any number of properties, which
        !           131:     themselves differ. In <a href="#77004">Figure 10-2</a>,
        !           132:     <i>wrote</i> is a property of <i>Eric</i>. However, resources
        !           133:     can also have multiple properties, as shown in <a href=
        !           134:     "#77006">Figure 10-3</a>.</p>
        !           135:     <div class="c22">
        !           136:       <img src="foo.gif">
        !           137:     </div>
        !           138:     <p><i>Figure 10-3: <a name="77006"></a></i> <i>RDF Graph with
        !           139:     five nodes</i></p>
        !           140:     <p>The RDF graph in <a href="#77006">Figure 10-3</a> has five
        !           141:     nodes, two resources, and three literals. If this graph were
        !           142:     represented in XML, it would probably have three different XML
        !           143:     namespaces inside of it: RDF/XML, a <i>book</i> XML
        !           144:     specification, and a <i>computer</i> XML specification. In
        !           145:     English, the graph in <a href="#77006">Figure 10-3</a> might be
        !           146:     expressed as follows:</p>
        !           147:     <blockquote>
        !           148:       Eric wrote a book of unknown information. Eric's computer is
        !           149:       700 MHz and has an Athlon CPU.
        !           150:     </blockquote>
        !           151:     <p>Note that if Eric wrote a poem and a book, it would be
        !           152:     possible to have two <i>wrote</i> properties for the same
        !           153:     resource. Using the same property to point to separate
        !           154:     resources is confusing, however. Instead, RDF containers (see
        !           155:     the section <a href="#77069">"RDF containers</a>," later in
        !           156:     this chapter) are the best way to organize data that would
        !           157:     otherwise need a single property to branch in this way.</p>
        !           158:     <h4><a name="77064"></a> RDF URIs relating to namespaces</h4>
        !           159:     <p>The 
        !           160:     <!--INDEX RDF (Resource Description Framework):data model:URIs -->
        !           161:     <!--INDEX data model (RDF):URIs --> <!--INDEX URIs (Universal 
        !           162:     Resource Identifiers):RDF:namespaces --> 
        !           163:     <!--INDEX namespaces:RDF, URIs and --> URIs used in RDF can be
        !           164:     part of the element namespace. (See <a href=
        !           165:     "ch02.html#77053">"The XUL Namespace" in Chapter 2</a> and in
        !           166:     <a href="ch07.html#77031">"Namespaces and XBL" in Chapter 7</a>
        !           167:     for more information about XML namespaces.) This use is
        !           168:     especially true for properties. Some namespaces can be created
        !           169:     from previous examples:</p>
        !           170: <pre>
        !           171: xmlns:rdf="<a href=
        !           172: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           173: xmlns:book="<a href=
        !           174: "http://www.oreilly.com/rdf">http://www.oreilly.com/rdf</a>#"
        !           175: xmlns:comp="my.computer.hardware#"
        !           176: </pre>
        !           177:     <p>When you use namespaces, the graph looks much different, as
        !           178:     shown in <a href="#77008">Figure 10-4</a>.</p>
        !           179:     <div class="c22">
        !           180:       <img src="foo.gif">
        !           181:     </div>
        !           182:     <p><i>Figure 10-4: <a name="77008"></a></i> <i>Namespaces
        !           183:     applied to Figure 10-3</i></p>
        !           184:     <blockquote>
        !           185:       <div class="c21">
        !           186:         NOTE
        !           187:       </div>
        !           188:       <p>The resource identifier is often displayed in a URL format
        !           189:       too, but it shouldn't use the same namespace URL as the
        !           190:       RDF/XML file. The URL typically tries to describe a unique
        !           191:       object, such as <i><a href=
        !           192:       "http://my.jar-of-flies.com">http://my.jar-of-flies.com</a></i>.</p>
        !           193:     </blockquote>
        !           194:     <h4><a name="77065"></a> RDF triples: subject, predicate, and
        !           195:     object</h4>
        !           196:     <p>A triple <!--INDEX statements, RDF, triples --> 
        !           197:     <!--INDEX triples:RDF statements --> 
        !           198:     <!--INDEX RDF (Resource Description Framework):statements, triples -->
        !           199:     is a type of RDF statement. While an RDF statement can be a
        !           200:     loose collection of resources, properties, and literals, a
        !           201:     triple typically defines a tighter relationship between such
        !           202:     elements.</p>
        !           203:     <p>The first part of a triple is the <i>subject</i>. This part
        !           204:     is the resource described by the triple. The second part of the
        !           205:     triple is the <i>predicate</i>. This part is a subject's
        !           206:     property, a thing that joins it with something else. The third
        !           207:     part is the <i>object</i>, which is either a resource or a
        !           208:     literal.</p>
        !           209:     <p>RDF triples are significant because their stricter semantics
        !           210:     guarantee the relationship between parts. A triple is a more
        !           211:     formal version of the RDF statement, which is used more
        !           212:     broadly. In <a href="#77008">Figure 10-4</a>, all statements
        !           213:     are formally subject &gt; predicate &gt; object, so those
        !           214:     statements are triples.</p>
        !           215:     <h4><a name="77066"></a> RDF data model terminology</h4>
        !           216:     <p>When 
        !           217:     <!--INDEX RDF (Resource Description Framework):data model:terminology -->
        !           218:     <!--INDEX data model (RDF):terminology --> reading RDF
        !           219:     specifications, documentation, examples, and other related
        !           220:     material on the Internet, you can encounter a dizzying array of
        !           221:     terms that mean the same thing. <a href="#77020">Table 10-1</a>
        !           222:     should help clarify these different terms. The italicized
        !           223:     versions of the synonyms all do not technically mean the same
        !           224:     thing, but are loose synonyms whose meanings depend on the
        !           225:     context in which they are used.</p>
        !           226:     <p><i>Table 10-1: <a name="77020"></a></i> <i>Synonyms in
        !           227:     RDF</i></p>
        !           228:     <table width="100%" border="1">
        !           229:       <tr>
        !           230:         <td><b>Common term</b></td>
        !           231:         <td><b>Synonyms</b></td>
        !           232:       </tr>
        !           233:       <tr>
        !           234:         <td>Resource</td>
        !           235:         <td>Subject, object</td>
        !           236:       </tr>
        !           237:       <tr>
        !           238:         <td>Resource identifier</td>
        !           239:         <td>Name, (resource) URI, ID, identifier, URL, label</td>
        !           240:       </tr>
        !           241:       <tr>
        !           242:         <td>Properties</td>
        !           243:         <td>Attributes</td>
        !           244:       </tr>
        !           245:       <tr>
        !           246:         <td>Statement</td>
        !           247:         <td>Triple, tuple, binding, assertion</td>
        !           248:       </tr>
        !           249:       <tr>
        !           250:         <td>Subject</td>
        !           251:         <td>Source, resource, node, root</td>
        !           252:       </tr>
        !           253:       <tr>
        !           254:         <td>Predicate</td>
        !           255:         <td>Arc, (statement) URI, property, atom</td>
        !           256:       </tr>
        !           257:       <tr>
        !           258:         <td>Object</td>
        !           259:         <td>Value, resource, node, literal</td>
        !           260:       </tr>
        !           261:     </table>
        !           262:     <h3><a name="77067"></a> RDF Syntax</h3>
        !           263:     <p>Mozilla 
        !           264:     <!--INDEX RDF (Resource Description Framework):syntax:overview -->
        !           265:     <!--INDEX syntax, RDF:overview --> uses XML to represent RDF
        !           266:     data. In 1999, the W3C defined the RDF/XML specification syntax
        !           267:     to make it the most common way RDF is used. The RDF/XML format
        !           268:     is sometimes called the RDF serialization syntax because it
        !           269:     allows RDF models to be sent easily from one computer
        !           270:     application to another in a common XML format.</p>
        !           271:     <p>When an application reads an RDF file, the Mozilla RDF
        !           272:     processor builds a graphical interpretation in-memory. In this
        !           273:     section, you learn how to build an RDF file from scratch and
        !           274:     see what the graph looks like after running through Mozilla's
        !           275:     RDF processor.</p>
        !           276:     <blockquote>
        !           277:       <div class="c21">
        !           278:         NOTE
        !           279:       </div>
        !           280:       <p><tt>RDF:RDF</tt> is a common namespace representation of
        !           281:       RDF/XML data and is the one most frequently used in Mozilla
        !           282:       files. However, it can be hard to read, so this chapter uses
        !           283:       <tt>rdf:RDF</tt>. The W3C also used <tt>rdf:RDF</tt> in the
        !           284:       RDF recommendation document.</p>
        !           285:     </blockquote>
        !           286:     <h4><a name="77068"></a> Examining a simple RDF file</h4>
        !           287:     <p>We begin 
        !           288:     <!--INDEX RDF (Resource Description Framework):syntax:files -->
        !           289:     <!--INDEX syntax, RDF:files --> <!--INDEX files:RDF:syntax -->
        !           290:     with an example of an RDF file whose basic layout and simple
        !           291:     syntax can be a model for the more advanced data introduced
        !           292:     later. The RDF file shown in <a href="#77026">Example 10-1</a>
        !           293:     is a list of three types of "flies," with the context of those
        !           294:     "flies" inside a "jar." <a href="#77026">Example 10-1</a> also
        !           295:     contains a namespace that defines these types of flies and
        !           296:     shows the <tt>rdf</tt> and <tt>fly</tt> XML intertwined.</p>
        !           297:     <p><i>Example 10-1: <a name="77026"></a></i> <i>Simple RDF file
        !           298:     with "fly" namespace</i></p>
        !           299: <pre>
        !           300:    &lt;?xml version="1.0"?&gt;
1.1       david     301:    &lt;rdf:RDF
1.9     ! petejc    302:       xmlns:rdf="<a href=
        !           303: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           304:       xmlns:fly="<a href=
        !           305: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"&gt;
        !           306:      &lt;rdf:Description about="<a href=
        !           307: "http://my.jar-of-flies.com">http://my.jar-of-flies.com</a>"&gt;
1.1       david     308:        &lt;fly:types&gt;
                    309:          &lt;rdf:Bag&gt;
                    310:            &lt;rdf:li&gt;
                    311:              &lt;rdf:Description fly:name="Horse"/&gt;
                    312:            &lt;/rdf:li&gt;
                    313:            &lt;rdf:li&gt;
                    314:              &lt;rdf:Description fly:name="House"/&gt;
                    315:            &lt;/rdf:li&gt;
                    316:            &lt;rdf:li&gt;
                    317:              &lt;rdf:Description fly:name="Fruit"/&gt;
                    318:            &lt;/rdf:li&gt;
                    319:          &lt;/rdf:Bag&gt;
                    320:        &lt;/fly:types&gt;
                    321:      &lt;/rdf:Description&gt;
1.9     ! petejc    322:    &lt;/rdf:RDF&gt;
        !           323: </pre>
        !           324:     <p><tt><!--INDEX rdf\:Description element -->
        !           325:     &lt;rdf:Description&gt;</tt> is the tag used to outline a
        !           326:     resource. <a href="#77026">Example 10-1</a> shows how the
        !           327:     <tt>about</tt> attribute references the resource identifier and
        !           328:     makes this resource unique in the document. Two resources
        !           329:     cannot have the same <tt>about</tt> value in a document, just
        !           330:     as tags cannot share an <tt>id</tt> in an XML document. Both
        !           331:     attributes guarantee the unique nature of each element and
        !           332:     relationship.</p>
        !           333: <pre>
        !           334: &lt;rdf:Description about="<a href=
        !           335: "http://my.jar-of-flies.com">http://my.jar-of-flies.com</a>"&gt;
1.1       david     336: &lt;fly:types&gt;
1.9     ! petejc    337: &lt;rdf:Bag&gt;
        !           338: </pre>
        !           339:     <p><tt><a href=
        !           340:     "http://my.jar-of-flies.com">http://my.jar-of-flies.com</a></tt>,
        !           341:     is the subject shown in the previous code snippet. <i>My jar of
        !           342:     flies</i> is a resource definition and defines only what
        !           343:     <i>flies</i> are inside of the statement. The predicate, which
        !           344:     addresses a property in the resource, is defined by the tag
        !           345:     <tt>&lt;types&gt;</tt> (of the <tt><a href=
        !           346:     "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#</tt>
        !           347:     namespace).</p>
        !           348:     <p>The final part of the statement, the object, is the actual
        !           349:     data of the predicate and a container of type bag. The
        !           350:     container is an RDF resource that "holds," or points to, a
        !           351:     collection of other resources. In the next section, container
        !           352:     types are discussed in depth. <a href="#77010">Figure 10-5</a>
        !           353:     illustrates how the triple originates from the root subject and
        !           354:     includes the container object.</p>
        !           355:     <div class="c22">
        !           356:       <img src="foo.gif">
        !           357:     </div>
        !           358:     <p><i>Figure 10-5: <a name="77010"></a></i> <i>The first
        !           359:     statement of the graph, with labeled parts</i></p>
        !           360:     <p>In this case, an RDF statement is extracted from the
        !           361:     example, but no useful data is reached. Little can be done with
        !           362:     an empty RDF container, and two more steps are needed to reach
        !           363:     literals that contain names of the flies.</p>
        !           364:     <h4><a name="77069"></a> RDF containers</h4>
        !           365:     <p>Containers 
        !           366:     <!--INDEX RDF (Resource Description Framework):containers --> 
        !           367:     <!--INDEX containers:RDF --> are a list of resources or
        !           368:     literals. They are a form of RDF 
        !           369:     <!--INDEX resources:RDF:containers --> resource. There are
        !           370:     three different container types: <tt>bag</tt>,
        !           371:     <tt>sequence</tt>, and <tt>alternative</tt>. <tt>Bag</tt> is an
        !           372:     unordered list of items, whereas <tt>sequence</tt> is an
        !           373:     ordered list of items. They both allow duplicate values.
        !           374:     <tt>Alternative</tt> is a list of values that could replace a
        !           375:     particular property in a resource. <tt>Sequence</tt> is the
        !           376:     most popular container for use in Mozilla applications because
        !           377:     it frequently uses ordered lists of data. A container's
        !           378:     graphical definition is an entire separate statement about its
        !           379:     type and the items it contains. In <a href="#77012">Figure
        !           380:     10-6</a>, you can see the type of the container defined in the
        !           381:     RDF statement with the property <tt>rdf:type</tt>. The
        !           382:     remaining properties are the container's items.</p>
        !           383:     <div class="c22">
        !           384:       <img src="foo.gif">
        !           385:     </div>
        !           386:     <p><i>Figure 10-6: <a name="77012"></a></i> <i>The second
        !           387:     statement of the graph, with labeled parts</i></p>
        !           388:     <p>Once the container is defined, you can examine its
        !           389:     collection of elements. At this point in the RDF code, direct
        !           390:     comparisons can again be made from the code to the graph:</p>
        !           391: <pre>
        !           392: &lt;rdf:Bag&gt;
1.1       david     393: &lt;rdf:li&gt;
1.9     ! petejc    394: &lt;rdf:Description ...
        !           395: </pre>
        !           396:     <p>Here, the <tt><!--INDEX rdf\:li tag --> &lt;rdf:li&gt;</tt>
        !           397:     tag is similar to the <tt>&lt;li&gt;</tt> tag in HTML, which
        !           398:     stands for "list item." Moving from code to graph, the new
        !           399:     representation is shown in <a href="#77012">Figure
        !           400:     10-6</a>.</p>
        !           401:     <p>In <a href="#77012">Figure 10-6</a>, the subject is the
        !           402:     instance of the container. This statement does not begin from
        !           403:     <tt>rdf:Bag</tt> because that resource is only a type
        !           404:     definition. The actual items in the container originate from
        !           405:     the instance created in memory by any RDF processor, including
        !           406:     Mozilla's.</p>
        !           407:     <blockquote>
        !           408:       <div class="c21">
        !           409:         NOTE
        !           410:       </div>
        !           411:       <p>Mozilla's RDF processor fills in the <tt>rdf:*(1)</tt> of
        !           412:       the resource identifier in <a href="#77012">Figure 10-6</a>
        !           413:       with a hashed value. The same is true for the container's
        !           414:       resource identifier. The actual values come out as something
        !           415:       like <tt>rdf:#$0mhkm1</tt>, though the values change each
        !           416:       time the RDF document is loaded.</p>
        !           417:     </blockquote>
        !           418:     <p>Objects inside of the container have 
        !           419:     <!--INDEX properties:RDF:containers --> properties identified
        !           420:     automatically as <tt>rdf:_1</tt>, <tt>rdf:_2</tt>, etc., as
        !           421:     defined by the RDF model specification. However, RDF
        !           422:     applications such as Mozilla may use different identifiers to
        !           423:     differentiate list objects.</p>
        !           424:     <h4><a name="77070"></a> Literals</h4>
        !           425:     <p>The final 
        !           426:     <!--INDEX RDF (Resource Description Framework):literals -->
        !           427:     statement in <a href="#77026">Example 10-1</a> allows the
        !           428:     predicate to reach the text data, the literal "horse" shown in
        !           429:     <a href="#77014">Figure 10-7</a>. Note that the <tt>about</tt>
        !           430:     reference on the <tt>Description</tt> is fictitious RDF, but it
        !           431:     demonstrates the difference between a resource and a
        !           432:     literal.</p>
        !           433: <pre>
        !           434: &lt;rdf:Description about="rdf:*(1)" fly:name="Horse"/&gt;
        !           435: </pre>
        !           436:     <div class="c22">
        !           437:       <img src="foo.gif">
        !           438:     </div>
        !           439:     <p><i>Figure 10-7: <a name="77014"></a></i> <i>The third
        !           440:     statement of the graph, with labeled parts</i></p>
        !           441:     <p>The previous RDF 
        !           442:     <!--INDEX RDF (Resource Description Framework):syntax:shorthand -->
        !           443:     <!--INDEX syntax, RDF:shorthand --> code for the literal is
        !           444:     syntactic shorthand. Using this type of shortcut can make RDF
        !           445:     much easier to read. The previous code snippet is the same as
        !           446:     the longer and more cumbersome one shown here:</p>
        !           447: <pre>
        !           448: &lt;rdf:Description about="rdf:*(1)"&gt;
1.1       david     449: &lt;fly:name&gt;Horse&lt;/fly:name&gt;
1.9     ! petejc    450: &lt;/rdf:Description&gt;
        !           451: </pre>
        !           452:     <p>The shorthand version of this statement can be useful when
        !           453:     you have a lot of data or when you want to use one syntax to
        !           454:     show all relationships in the graph.</p>
        !           455:     <h4><a name="77071"></a> The RDF syntax and RDF graphs</h4>
        !           456:     <p><a href="#77016">Figure 10-8</a> shows the entire RDF graph
        !           457:     for the RDF file in <a href="#77026">Example 10-1</a>. This
        !           458:     graph was compiled by combining the concepts you've seen in
        !           459:     Figures 10-5 through 10-7.</p>
        !           460:     <p>As you can see, the statements fit together quite nicely.
        !           461:     Four resources originate from the container, and one is the
        !           462:     container type definition. The other two properties are
        !           463:     numbered according to their order in the RDF file.</p>
        !           464:     <div class="c22">
        !           465:       <img src="foo.gif">
        !           466:     </div>
        !           467:     <p><i>Figure 10-8: <a name="77016"></a></i> <i>The full
        !           468:     graph</i></p>
        !           469:     <h3><a name="77072"></a> Building an RDF File from Scratch</h3>
        !           470:     <p>Now that 
        !           471:     <!--INDEX RDF (Resource Description Framework):files:creating -->
        !           472:     <!--INDEX files:RDF:creating --> you understand the basic
        !           473:     principles of a simple RDF file, this section steps through the
        !           474:     creation of an RDF file from information found in regular
        !           475:     text:</p>
        !           476:     <blockquote>
        !           477:       There is a jar with the name urn:root. Inside of it there are
        !           478:       two types of flies listed as House and Horse. There are three
        !           479:       Horse flies. The Face Fly, coded in green, is officially
        !           480:       identified as "musca autumnalis". The Stable Fly, coded in
        !           481:       black, has the identification "stomoxys_calcitrans." The
        !           482:       red-coded Horn Fly, located in Kansas, is identified as
        !           483:       "haematobia_irritans." There are also three house flies.
        !           484:       "musca_domestica," coded in brown, has the name "Common House
        !           485:       Fly." A gray fly named "Carrion Fly" has the ID "sarcophagid"
        !           486:       and is found globally. Finally, The "Office Fly," coded with
        !           487:       white, is prevalent in the Bay Area.
        !           488:     </blockquote>
        !           489:     <p>You can use the techniques described here to model the data
        !           490:     you want in your application: spreadsheet-like rosters of
        !           491:     people, family trees, or catalogs of books or other items.</p>
        !           492:     <h4><a name="77073"></a> Identify namespaces</h4>
        !           493:     <p>The new 
        !           494:     <!--INDEX namespaces:identifying, creating RDF files --> 
        !           495:     <!--INDEX RDF (Resource Description Framework):files:identifying namespaces -->
        !           496:     <!--INDEX files:RDF:identifying namespaces --> RDF file will
        !           497:     have three namespaces including the RDF namespace. The result
        !           498:     is two different data types that are connected in an RDF graph.
        !           499:     For the sake of the example, one namespace is not in the
        !           500:     standard URL format. Here is how the RDF file namespaces are
        !           501:     set up:</p>
        !           502: <pre>
        !           503: &lt;?xml version="1.0"?&gt;
        !           504: &lt;rdf:RDF xmlns:rdf="<a href=
        !           505: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           506: xmlns:fly="<a href=
        !           507: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
1.1       david     508: xmlns:location="fly-location#"&gt;
1.9     ! petejc    509: &lt;/rdf:RDF&gt;
        !           510: </pre>
        !           511:     <h4><a name="77074"></a> Root resource</h4>
        !           512:     <p>This file's <!--INDEX resources:RDF:creating files --> 
        !           513:     <!--INDEX root resources, RDF files --> 
        !           514:     <!--INDEX RDF (Resource Description Framework):files:root resources -->
        !           515:     <!--INDEX files:RDF:root resources --> root resource is an
        !           516:     <tt>urn:root</tt>, which is the conventional name for root
        !           517:     nodes in Mozilla's RDF files. When rendering RDF files,
        !           518:     defining a root node for processing the document can be
        !           519:     useful-especially when building templates. This root node can
        !           520:     be entered as the first item in the file:</p>
        !           521: <pre>
        !           522: &lt;?xml version="1.0"?&gt;
        !           523: &lt;rdf:RDF xmlns:rdf="<a href=
        !           524: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           525: xmlns:fly="<a href=
        !           526: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
1.1       david     527: xmlns:location="fly-location#"&gt;
                    528: &lt;rdf:Description about="urn:root"&gt;
                    529: &lt;/rdf:Description&gt;
1.9     ! petejc    530: &lt;/rdf:RDF&gt;
        !           531: </pre>
        !           532:     <h4><a name="77075"></a> Root sequence</h4>
        !           533:     <p>Next, a <!--INDEX sequences, RDF:creating files --> 
        !           534:     <!--INDEX root sequences, RDF files --> 
        !           535:     <!--INDEX RDF (Resource Description Framework):files:root sequesces -->
        !           536:     <!--INDEX files:RDF:root sequesces --> generic tag needs to be
        !           537:     used to specify a sequence of "fly" data. As in <a href=
        !           538:     "#77028">Example 10-2</a>, <tt>&lt;fly:list&gt;</tt> is used as
        !           539:     a list of fly types. This tag is a generic name because of the
        !           540:     way XUL templates process lists of RDF data. If a list of data
        !           541:     has sublists, as in the following examples, then they must use
        !           542:     the same tag name to recurse correctly for the data they
        !           543:     contain.</p>
        !           544:     <p><a href="#77028">Example 10-2</a> represents all the
        !           545:     information given in the first paragraph of the text example:
        !           546:     "There is a jar set up with the name <i>urn:root</i>. Inside of
        !           547:     it there are two types of flies, listed as House and
        !           548:     Horse."</p>
        !           549:     <p><i>Example 10-2: <a name="77028"></a></i> <i>RDF root
        !           550:     sequence</i></p>
        !           551: <pre>
        !           552:  &lt;?xml version="1.0"?&gt;
        !           553:  &lt;rdf:RDF xmlns:rdf="<a href=
        !           554: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           555:           xmlns:fly="<a href=
        !           556: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
1.1       david     557:           xmlns:location="fly-location#"&gt;
                    558:    &lt;rdf:Description about="urn:root"&gt;
                    559:      &lt;fly:list&gt;
                    560:        &lt;rdf:Seq&gt;
                    561:          &lt;rdf:li&gt;
                    562:            &lt;rdf:Description ID="House" fly:label="House"/&gt;
                    563:          &lt;/rdf:li&gt;
                    564:          &lt;rdf:li&gt;
                    565:            &lt;rdf:Description ID="Horse" fly:label="Horse"/&gt;
                    566:          &lt;/rdf:li&gt;
                    567:        &lt;/rdf:Seq&gt;
                    568:      &lt;/fly:list&gt;
                    569:    &lt;/rdf:Description&gt;
1.9     ! petejc    570:  &lt;/rdf:RDF&gt;
        !           571: </pre>
        !           572:     <p>An RDF sequence resides with its list of resources inside
        !           573:     <tt>&lt;fly:list&gt;</tt>. Here, shorthand RDF specifies a
        !           574:     label with the <tt>fly:label</tt> attribute. The <tt>ID</tt>
        !           575:     attribute within this sequence is actually a pointer to the
        !           576:     main definition of the resource described by an <tt>about</tt>
        !           577:     attribute of the same value. The <tt>about</tt> attribute
        !           578:     includes a <tt>#</tt> in its identifier, much like HTML anchors
        !           579:     use <tt>&lt;a href="#frag"&gt;</tt> to refer to <tt>&lt;a
        !           580:     name="frag"&gt;</tt>. For example, <tt>ID="Horse"</tt> points
        !           581:     to <tt>about="#Horse</tt>" elsewhere in the file, allowing you
        !           582:     to add to the description of any element with new properties
        !           583:     and resources.</p>
        !           584:     <h4><a name="77076"></a> Secondary sequences and literals</h4>
        !           585:     <p>The <!--INDEX sequences, RDF:creating files --> 
        !           586:     <!--INDEX secondary sequences, RDF files --> 
        !           587:     <!--INDEX RDF (Resource Description Framework):files:secondary sequesces -->
        !           588:     <!--INDEX files:RDF:secondary sequesces --> <tt>Horse</tt> and
        !           589:     <tt>House</tt> resources need to be defined next. <a href=
        !           590:     "#77030">Example 10-3</a> shows the creation of <tt>Horse</tt>
        !           591:     from the second paragraph. The process for creating
        !           592:     <tt>House</tt> is almost identical.</p>
        !           593:     <p><i>Example 10-3: <a name="77030"></a></i> <i>The Horse
        !           594:     sequence</i></p>
        !           595: <pre>
        !           596:  &lt;rdf:Description about="#Horse"&gt;
1.1       david     597:      &lt;fly:list&gt;
                    598:        &lt;rdf:Seq&gt;
                    599:          &lt;rdf:li&gt;
                    600:            &lt;rdf:Description about="musca_autumnalis"
                    601:                             fly:label="Face fly"
                    602:                             fly:color="green"/&gt;
                    603:          &lt;/rdf:li&gt;
                    604:          &lt;rdf:li&gt;
                    605:            &lt;rdf:Description about="stomoxys_calcitrans"
                    606:                             fly:label="Stable Fly"
                    607:                             fly:color="black"/&gt;
                    608:          &lt;/rdf:li&gt;
                    609:          &lt;rdf:li&gt;
                    610:            &lt;rdf:Description about="haematobia_irritans"
                    611:                             fly:label="Horn Fly"
                    612:                             fly:color="red"
                    613:                             location:location="Kansas"/&gt;
                    614:          &lt;/rdf:li&gt;
                    615:        &lt;/rdf:Seq&gt;
                    616:      &lt;/fly:list&gt;
1.9     ! petejc    617:    &lt;/rdf:Description&gt;
        !           618: </pre>
        !           619:     <p>Here the shorthand RDF definition continues to use only the
        !           620:     attributes. Again, a <tt>&lt;fly:list&gt;</tt> is defined and
        !           621:     the items inside it are listed. The listed values have multiple
        !           622:     attribute values, all of which are RDF literals. In longhand
        !           623:     with RDF showing all literals, the last item would be written
        !           624:     out as follows:</p>
        !           625: <pre>
        !           626: &lt;rdf:li&gt;
1.1       david     627: &lt;rdf:Description about="haematobia_irritans "&gt;
                    628: &lt;fly:label&gt;Horn Fly&lt;/fly:label&gt;
                    629: &lt;fly:color&gt;red&lt;/fly:color&gt;
                    630: &lt;location:location&gt;Kansas&lt;/location:location&gt;
                    631: &lt;/rdf:Description&gt;
1.9     ! petejc    632: &lt;/rdf:li&gt;
        !           633: </pre>
        !           634:     <p>The two different namespace literals are both resource
        !           635:     attributes. <tt>haematobia_irritans</tt> is used as the
        !           636:     resource identifier because it is a unique value among all
        !           637:     data.</p>
        !           638:     <p>Laying out the data in the same pattern gives you the final,
        !           639:     full RDF file in <a href="#77032">Example 10-4</a>.</p>
        !           640:     <p><i>Example 10-4: <a name="77032"></a></i> <i>Entire RDF
        !           641:     file</i></p>
        !           642: <pre>
        !           643:  &lt;?xml version="1.0"?&gt;
        !           644:  &lt;rdf:RDF xmlns:rdf="<a href=
        !           645: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !           646:           xmlns:fly="<a href=
        !           647: "http://xfly.mozdev.org/fly-rdf">http://xfly.mozdev.org/fly-rdf</a>#"
1.1       david     648:           xmlns:location="fly-location#"&gt;
                    649:    &lt;rdf:Description about="urn:root"&gt;
                    650:      &lt;fly:list&gt;
                    651:        &lt;rdf:Seq&gt;
                    652:          &lt;rdf:li&gt;
                    653:            &lt;rdf:Description ID="House" fly:label="House"/&gt;
                    654:          &lt;/rdf:li&gt;
                    655:          &lt;rdf:li&gt;
                    656:            &lt;rdf:Description ID="Horse" fly:label="Horse"/&gt;
                    657:          &lt;/rdf:li&gt;
                    658:        &lt;/rdf:Seq&gt;
                    659:      &lt;/fly:list&gt;
                    660:    &lt;/rdf:Description&gt;
                    661:    &lt;rdf:Description about="#Horse"&gt;
                    662:      &lt;fly:list&gt;
                    663:        &lt;rdf:Seq&gt;
                    664:          &lt;rdf:li&gt;
                    665:            &lt;rdf:Description about="musca_autumnalis"
                    666:                             fly:label="Face fly"
                    667:                             fly:color="green"/&gt;
                    668:          &lt;/rdf:li&gt;
                    669:          &lt;rdf:li&gt;
                    670:            &lt;rdf:Description about="stomoxys_calcitrans"
                    671:                             fly:label="Stable Fly"
                    672:                             fly:color="black"/&gt;
                    673:          &lt;/rdf:li&gt;
                    674:          &lt;rdf:li&gt;
                    675:            &lt;rdf:Description about="haematobia_irritans"
                    676:                             fly:label="Horn Fly"
                    677:                             fly:color="red"
                    678:                             location:location="Kansas"/&gt;
                    679:          &lt;/rdf:li&gt;
                    680:        &lt;/rdf:Seq&gt;
                    681:      &lt;/fly:list&gt;
                    682:    &lt;/rdf:Description&gt;
                    683:    &lt;rdf:Description about="#House"&gt;
                    684:      &lt;fly:list&gt;
                    685:        &lt;rdf:Seq&gt;
                    686:          &lt;rdf:li&gt;
                    687:            &lt;rdf:Description about="musca_domestica"
                    688:                             fly:label="Common House Fly"
                    689:                             fly:color="brown"/&gt;
                    690:          &lt;/rdf:li&gt;
                    691:          &lt;rdf:li&gt;
                    692:            &lt;rdf:Description about="sarcophagid"
                    693:                             fly:label="Carrion Fly"
                    694:                             fly:color="gray"
                    695:                             location:location="Worldwide"/&gt;
                    696:          &lt;/rdf:li&gt;
                    697:          &lt;rdf:li&gt;
                    698:            &lt;rdf:Description about="musca_oficio"
                    699:                             fly:label="Office Fly"
                    700:                             fly:color="white"
                    701:                             location:location="California, Bay Area"/&gt;
                    702:          &lt;/rdf:li&gt;
                    703:        &lt;/rdf:Seq&gt;
                    704:      &lt;/fly:list&gt;
                    705:    &lt;/rdf:Description&gt;
1.9     ! petejc    706:  &lt;/rdf:RDF&gt;
        !           707: </pre>
        !           708:     <p><a href="#77032">Example 10-4</a> shows the RDF data used in
        !           709:     several template examples in <a href="ch09.html#77034">Chapter
        !           710:     9</a>. <a href="ch09.html#77022">Example 9-4</a> includes the
        !           711:     <i>10-4.rdf</i> datasource, as do many of those templates. You
        !           712:     can copy the data out of <a href="#77032">Example 10-4</a> and
        !           713:     into a file of the same name to use as a datasource.</p>
        !           714:     <h2><a name="77077"></a> The Mozilla Content Model</h2>
        !           715:     <p>One theme <!--INDEX content model:overview --> 
        !           716:     <!--INDEX Gecko rendering engine:Mozilla content model --> of
        !           717:     this book-and a general goal of the Mozilla development
        !           718:     environment-is that developers can create real applications
        !           719:     using many of the same technologies they use to create a web
        !           720:     page. The Gecko rendering engine, sitting at the heart of
        !           721:     Mozilla and happily rendering web content, XML files, XUL
        !           722:     interfaces, and whatever else they can support, is what makes
        !           723:     this type of development possible. But how does Gecko know what
        !           724:     to render and how? How can RDF data be handed over so that
        !           725:     Gecko knows how to draw it?</p>
        !           726:     <p>When a browser uses the same engine to draw everything-its
        !           727:     own interface as well as the various kinds of content it
        !           728:     supports-that engine treats everything as content. Gecko needs
        !           729:     a way to understand all the various parts of the Mozilla
        !           730:     browser itself-such as the sidebar, the toolbars, and the mail
        !           731:     folders and mail messages-as resources it can render and
        !           732:     display in the Mozilla chrome. This approach to the Mozilla
        !           733:     application interface is called the content model.</p>
        !           734:     <p>In Mozilla's content model, XUL documents and other
        !           735:     interface resources are transformed into RDF when they are
        !           736:     read. Each chunk of content is represented as a separate RDF
        !           737:     datasource (see the next section, <a href=
        !           738:     "#77078">"Datasources</a>," for more information) and is then
        !           739:     fed to the XUL Content Builder and rendered as the actual bits
        !           740:     on the screen, as <a href="#77018">Figure 10-9</a> shows.</p>
        !           741:     <div class="c22">
        !           742:       <img src="foo.gif">
        !           743:     </div>
        !           744:     <p><i>Figure 10-9: <a name="77018"></a></i> <i>Diagram of
        !           745:     Mozilla's content model</i></p>
        !           746:     <p>As you can see in <a href="#77018">Figure 10-9</a>, the
        !           747:     content model can be complex. The XUL documents in <a href=
        !           748:     "#77018">Figure 10-9</a> are files such as
        !           749:     <i>navigator.xul</i>, which defines the main browser window's
        !           750:     basic layout; the RDF documents include files like
        !           751:     <i>help-toc.rdf</i>, which defines the Mozilla Help viewer's
        !           752:     table of contents. The list of mail folders and accounts shown
        !           753:     in <a href="#77034">Example 10-5</a> are part of the built-in
        !           754:     data that Mozilla renders into browser content.</p>
        !           755:     <p>Whatever the source, the content model gets everything
        !           756:     processed in-memory as RDF so that any data can be combined and
        !           757:     formatted into XUL or other interface code. All sources of RDF
        !           758:     data are called datasources.</p>
        !           759:     <h3><a name="77078"></a> Datasources</h3>
        !           760:     <p>A datasource <!--INDEX content model:datasources --> 
        !           761:     <!--INDEX datasources:content model --> is a collection of
        !           762:     related, typically homogenous, RDF statements. A datasource may
        !           763:     be a single RDF file like <i>localstore.rdf</i>, a combination
        !           764:     of files, or RDF structures that exist only in memory (as
        !           765:     discussed later).</p>
        !           766:     <p>In Mozilla, datasources represent the messages in your email
        !           767:     inbox, your bookmarks, the packages you installed, your browser
        !           768:     history, and other sets of data. Datasources can be combined
        !           769:     easily (or "composed," which is where the term "composite
        !           770:     datasource" comes from).</p>
        !           771:     <h4><a name="77079"></a> A datasource example: mailboxes</h4>
        !           772:     <p>Several <!--INDEX content model:datasources:example --> 
        !           773:     <!--INDEX datasources:content model:example --> datasources
        !           774:     describe all the folders and messages in Mozilla's email. A
        !           775:     root datasource called <tt>msgaccounts</tt> describes which
        !           776:     mail servers and accounts are present. Separate datasources
        !           777:     then represent each account separately. These datasources are
        !           778:     composed to create the entire email storage system. The higher
        !           779:     levels of this content structure look like <a href=
        !           780:     "#77034">Example 10-5</a>.</p>
        !           781:     <p><i>Example 10-5: <a name="77034"></a></i> <i>Content model
        !           782:     of email datasources</i></p>
        !           783: <pre>
        !           784:  msgaccounts:/
        !           785:  +-- <a href=
        !           786: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
        !           787:      imap:&lt;/td&gt;<tt><i>//<a href=
        !           788: "MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</a></i></tt>
        !           789:      |    +-- <a href=
        !           790: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "true"
        !           791:      |    +-- <a href=
        !           792: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
        !           793:      |        imap:&lt;/td&gt;<tt><i>//<a href=
        !           794: "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a></i></tt>
        !           795:      |    +-- <a href=
        !           796: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#TotalMessages&lt;/td&gt; --&gt; "4"
        !           797:      |    +-- <a href=
        !           798: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "false"
        !           799:      |    +-- <a href=
        !           800: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
        !           801:      |        imap_message://<a href=
        !           802: "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a>#1
        !           803:      |    +-- <a href=
        !           804: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
        !           805:      |        imap_message://<a href=
        !           806: "MAILTO:oeschger@imap.netscape.com/INBOX">oeschger@imap.netscape.com/INBOX</a>#2
        !           807:      |    +-- <a href=
        !           808: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#MessageChild&lt;/td&gt; --&gt;
1.1       david     809:      |    etc...
                    810:      |
1.9     ! petejc    811:  +-- <a href=
        !           812: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
        !           813:      mailbox:&lt;/td&gt;<tt><i>//<a href=
        !           814: "MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</a></i></tt>
        !           815:      |    +-- <a href=
        !           816: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#IsServer&lt;/td&gt; --&gt; "true"
        !           817:      |    +-- <a href=
        !           818: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#child&lt;/td&gt; --&gt;
        !           819:      |        mailbox:&lt;/td&gt;<tt><i>//<a href=
        !           820: "MAILTO:oeschger@pop.oeschger.com/INBOX">oeschger@pop.oeschger.com/INBOX</a></i></tt>
        !           821:      |    +-- <a href=
        !           822: "http://home.netscape.com/NC-rdf">http://home.netscape.com/NC-rdf</a>#TotalMessages&lt;/td&gt; --&gt; "2"
        !           823:      |    etc...
        !           824: </pre>
        !           825:     <p>Each direct child of the root <i>msgaccounts:/</i> is a mail
        !           826:     server. This portion of the graph shows two Mozilla email
        !           827:     accounts that are the primary children: <i>imap://<a href=
        !           828:     "MAILTO:oeschger@imap.netscape.com">oeschger@imap.netscape.com</a></i>
        !           829:     and <i>mailbox://<a href=
        !           830:     "MAILTO:oeschger@pop.netscape.com">oeschger@pop.netscape.com</a></i>.
        !           831:     These two accounts are entirely different datasources that can
        !           832:     exist on their own. The content model for email actually
        !           833:     extends much lower than what is represented in this outline. It
        !           834:     uses RDF to represent the data all the way into the actual
        !           835:     message lists.</p>
        !           836:     <h4><a name="77080"></a> Types of datasources</h4>
        !           837:     <p>As you <!--INDEX content model:datasources:types --> 
        !           838:     <!--INDEX datasources:content model:types --> may have already
        !           839:     inferred, email accounts are not actually RDF files. Mozilla
        !           840:     provides a custom RDF map of all email accounts and messages
        !           841:     and the content model represents the accounts and their
        !           842:     relationships to one another as RDF so they can be integrated
        !           843:     and rendered properly. The interface to this custom mail RDF
        !           844:     map makes it possible to display a list of messages and
        !           845:     mailboxes in a <tt>&lt;tree&gt;</tt> template.</p>
        !           846:     <p>Another example of a datasource, the
        !           847:     <i>in-memory-datasource,</i> doesn't come from an actual RDF
        !           848:     file. When an in-memory datasource is created, it doesn't
        !           849:     contain data. However, data can be inserted into it and stored
        !           850:     in memory until the datasource is destroyed. In-memory
        !           851:     datasources frequently represent ephemeral data like search
        !           852:     results. Other basic datasource types are described in <a href=
        !           853:     "#77022">Table 10-2</a>.</p>
        !           854:     <p><i>Table 10-2: <a name="77022"></a></i> <i>Types of
        !           855:     datasources</i></p>
        !           856:     <i>all-packages.rdf</i>in the <i>chrome</i>directory, which
        !           857:     keeps track packages installed in Mozilla) are local
        !           858:     datasources.<i>assertions</i>, statements that build an
        !           859:     in-memory data model by adding resources, properties, and value
        !           860:     to those.<i>filesystem</i>datasource and a
        !           861:     <i>history</i>datasource.
        !           862:     <table width="100%" border="1">
        !           863:       <tr>
        !           864:         <td><b>Type</b></td>
        !           865:         <td><b>Description</b></td>
        !           866:       </tr>
        !           867:       <tr>
        !           868:         <td>Local datasource</td>
        !           869:         <td>A local datasource is an RDF graph contained in an
        !           870:         RDF/XML file on a local disk. All RDF files in the chrome
        !           871:         registry (e.g.,</td>
        !           872:       </tr>
        !           873:       <tr>
        !           874:         <td>Remote datasource</td>
        !           875:         <td>RDF can be accessed locally or remotely. A remote
        !           876:         datasource is an RDF/XML file stored on a server and
        !           877:         accessed with a URL.</td>
        !           878:       </tr>
        !           879:       <tr>
        !           880:         <td>In-memory datasource</td>
        !           881:         <td>An in-memory datasource exists only in memory during a
        !           882:         Mozilla session. In-memory datasources are built with</td>
        !           883:       </tr>
        !           884:       <tr>
        !           885:         <td>Built-in datasource</td>
        !           886:         <td>These unique, prefabricated datasources represent
        !           887:         something used often in Mozilla, such as a built-in</td>
        !           888:       </tr>
        !           889:       <tr>
        !           890:         <td>Composite datasource</td>
        !           891:         <td>A composite datasource may be a combination of any of
        !           892:         the datasources previously listed. RDF allows you to merge
        !           893:         different graphs.</td>
        !           894:       </tr>
        !           895:     </table>
        !           896:     <h2><a name="77081"></a> RDF Components and Interfaces</h2>
        !           897:     <p>Once you are comfortable using XUL templates to display RDF
        !           898:     data (see <a href="ch09.html#77034">Chapter 9</a>), you should
        !           899:     explore the various ways to create and change that data. In
        !           900:     Mozilla, data is generally RDF, since all data in Mozilla is
        !           901:     either represented formally in RDF or passed through the
        !           902:     RDF-based content model for display. Use the tools described in
        !           903:     this section to manipulate RDF and the data it represents.</p>
        !           904:     <p>Mozilla has a great set of interfaces for creating,
        !           905:     manipulating, and managing RDF, and it also provides ready-made
        !           906:     RDF components that represent datasources used in Mozilla.
        !           907:     Think of RDF interfaces as ways to manipulate RDF directly and
        !           908:     of RDF components as sets of the interfaces already associated
        !           909:     with a particular kind of data, such as bookmarks. Interfaces
        !           910:     tend to deal with the RDF model itself, without regard to the
        !           911:     kinds of data being handled, while RDF components give you
        !           912:     control over specific Mozilla data. See the next two sections
        !           913:     for more information on RDF interfaces and components.</p>
        !           914:     <h3><a name="77082"></a> What Is an RDF Component?</h3>
        !           915:     <p>An RDF 
        !           916:     <!--INDEX RDF (Resource Description Framework):components, overview -->
        !           917:     <!--INDEX components:RDF, overview --> component may implement
        !           918:     any number of the general RDF interfaces described here, in
        !           919:     addition to special interfaces for accessing and controlling
        !           920:     the data the datasource represents. For example,
        !           921:     <tt>@mozilla.org/rdf/data-source;1?name=internetsearch</tt> is
        !           922:     an RDF component used to control Mozilla's internet searching
        !           923:     facility. In Mozilla, a component can act as a library of code
        !           924:     specific to a given set of data or domain. The <tt>
        !           925:     <!--INDEX internetsearch component --> internetsearch</tt>
        !           926:     component is instantiated and used to recall text entered in a
        !           927:     previous search:</p>
        !           928: <pre>
        !           929: var searchDS = Components.classes["@mozilla.org/rdf/datasource;1?name=internetsearch"]
1.1       david     930: .getService(Components.interfaces.nsIInternetSearchService);
1.9     ! petejc    931: searchDS.RememberLastSearchText(escapedSearchStr);
        !           932: </pre>
        !           933:     <p>This RDF component implements an interface called <i>
        !           934:     <!--INDEX nsIInternetSearchService interface --> 
        !           935:     <!--INDEX interfaces:nsIInternetSearchService -->
        !           936:     nsIInternetSearchService</i>, which is selected from the
        !           937:     component and used to call the <tt>RememberLastSearchText</tt>
        !           938:     method. Although you can also use the <tt>getService</tt>
        !           939:     method to get one of a component's RDF interfaces (e.g., by
        !           940:     using
        !           941:     <tt>getService(Components.interfaces.nsIRDFDataSource)</tt>),
        !           942:     doing so is seldom necessary in practice. RDF components are
        !           943:     tailored to the datasources they represent and usually provide
        !           944:     all the access you need to access that data directly. <a href=
        !           945:     "#77036">Example 10-6</a> lists RDF components in Mozilla.</p>
        !           946:     <p><i>Example 10-6: <a name="77036"></a></i> <i>RDF-specific
        !           947:     components built into Mozilla</i></p>
        !           948: <pre>
        !           949:  @mozilla.org/rdf/container;1
1.1       david     950:  @mozilla.org/rdf/content-sink;1
                    951:  @mozilla.org/rdf/datasource;1?name=addresscard
                    952:  @mozilla.org/rdf/datasource;1?name=addressdirectory
                    953:  @mozilla.org/rdf/datasource;1?name=bookmarks
                    954:  @mozilla.org/rdf/datasource;1?name=charset-menu
                    955:  @mozilla.org/rdf/datasource;1?name=composite-datasource
                    956:  @mozilla.org/rdf/datasource;1?name=files
                    957:  @mozilla.org/rdf/datasource;1?name=history
                    958:  @mozilla.org/rdf/datasource;1?name=httpindex
                    959:  @mozilla.org/rdf/datasource;1?name=in-memory-datasource
                    960:  @mozilla.org/rdf/datasource;1?name=internetsearch
                    961:  @mozilla.org/rdf/datasource;1?name=ispdefaults
                    962:  @mozilla.org/rdf/datasource;1?name=local-store
                    963:  @mozilla.org/rdf/datasource;1?name=localsearch
                    964:  @mozilla.org/rdf/datasource;1?name=mailnewsfolders
                    965:  @mozilla.org/rdf/datasource;1?name=msgaccountmanager
                    966:  @mozilla.org/rdf/datasource;1?name=msgfilters
                    967:  @mozilla.org/rdf/datasource;1?name=msgnotifications
                    968:  @mozilla.org/rdf/datasource;1?name=smtp
                    969:  @mozilla.org/rdf/datasource;1?name=subscribe
                    970:  @mozilla.org/rdf/datasource;1?name=window-mediator
                    971:  @mozilla.org/rdf/datasource;1?name=xml-datasource
                    972:  @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=imap
                    973:  @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=mailbox
                    974:  @mozilla.org/rdf/delegate-factory;1?key=filter&amp;scheme=news
                    975:  @mozilla.org/rdf/delegate-factory;1?key=smtpserver&amp;scheme=smtp
                    976:  @mozilla.org/rdf/rdf-service;1
                    977:  @mozilla.org/rdf/resource-factory;1
                    978:  @mozilla.org/rdf/resource-factory;1?name=abdirectory
                    979:  @mozilla.org/rdf/resource-factory;1?name=abmdbcard
                    980:  @mozilla.org/rdf/resource-factory;1?name=abmdbdirectory
                    981:  @mozilla.org/rdf/resource-factory;1?name=imap
                    982:  @mozilla.org/rdf/resource-factory;1?name=mailbox
                    983:  @mozilla.org/rdf/resource-factory;1?name=news
                    984:  @mozilla.org/rdf/xml-parser;1
1.9     ! petejc    985:  @mozilla.org/rdf/xml-serializer;1
        !           986: </pre>
        !           987:     <p>From this list, components used often in the Mozilla source
        !           988:     code include bookmarks, history, mail and news folders, and
        !           989:     address books.</p>
        !           990:     <blockquote>
        !           991:       <hr>
        !           992:       <b>Special URIs</b> 
        !           993:       <p>Mozilla's built-in datasource 
        !           994:       <!--INDEX URIs (Universal Resource Identifiers):datasource components -->
        !           995:       <!--INDEX components:URIs --> components have special URIs
        !           996:       for access. Here is the format used to determine the URI from
        !           997:       the component reference:</p>
        !           998:       <p>Component:</p>
        !           999: <pre>
        !          1000: @mozilla.org/rdf/datasource;1?name=SomeName
        !          1001: </pre>
        !          1002:       Datasource URI: 
        !          1003: <pre>
        !          1004: rdf:SomeName
        !          1005: </pre>
        !          1006:       The URI is also accessible as a datasource property:
        !          1007:       <hr>
        !          1008:     </blockquote>
        !          1009:     foo-ds.URI 
        !          1010:     <h3><a name="77083"></a> What Are RDF Interfaces?</h3>
        !          1011:     <p>RDF interfaces 
        !          1012:     <!--INDEX RDF (Resource Description Framework):interfaces:overview -->
        !          1013:     <!--INDEX interfaces:RDF:overview --> are interfaces in Mozilla
        !          1014:     designed to manipulate RDF structures and data. They typically
        !          1015:     deal with RDF generally, rather than specific sets of data (as
        !          1016:     in the case of components). A common use for an RDF interface
        !          1017:     in JavaScript, shown in <a href="#77038">Example 10-7</a>, is
        !          1018:     to use <i>nsIRDFService</i> to retrieve or assert the root node
        !          1019:     of an RDF datasource.</p>
        !          1020:     <p><i>Example 10-7: <a name="77038"></a></i> <i>Creating a root
        !          1021:     node</i></p>
        !          1022: <pre>
        !          1023:  // get the nsIRDFService interface and assign it to RDF
        !          1024:  RDF = Components.classes&lt;/td&gt;<a href=
        !          1025: "MAILTO:[`@mozilla.org/rdf/rdf-service;1">[`@mozilla.org/rdf/rdf-service;1</a>'].
1.1       david    1026:        getService(Components.interfaces.nsIRDFService);
                   1027:  // call the GetResource method from the interface
1.9     ! petejc   1028:  rootResource = RDF.GetResource('urn:root');
        !          1029: </pre>
        !          1030:     <p>Like all Mozilla interfaces, RDF interfaces (shown in <a
        !          1031:     href="#77024">Table 10-3</a>) are defined in IDL and can be
        !          1032:     accessed through XPCOM. The examples in this section use
        !          1033:     JavaScript and XPConnect to access the components for
        !          1034:     simplicity, but you can also use these interfaces with C++, as
        !          1035:     they are often in the actual Mozilla source code. Most
        !          1036:     interfaces deal with datasources, which drive the use of RDF in
        !          1037:     Mozilla.</p>
        !          1038:     <p><i>Table 10-3: <a name="77024"></a></i> <i>Mozilla's
        !          1039:     built-in RDF interfaces</i></p>
        !          1040:     <tt>nsIRDFService</tt>.
        !          1041:     <table width="100%" border="1">
        !          1042:       <tr>
        !          1043:         <td><b>RDF interface</b></td>
        !          1044:         <td><b>Description</b></td>
        !          1045:       </tr>
        !          1046:       <tr>
        !          1047:         <td>nsIRDFService</td>
        !          1048:         <td>Mostly used for retrieving, datasources, resources, and
        !          1049:         literals. It also registers and unregisters datasources and
        !          1050:         resources.</td>
        !          1051:       </tr>
        !          1052:       <tr>
        !          1053:         <td>nsIRDFCompositeDataSource</td>
        !          1054:         <td>Allows the addition and removal of a datasource from a
        !          1055:         composite datasource (which may be empty).</td>
        !          1056:       </tr>
        !          1057:       <tr>
        !          1058:         <td>nsIRDFDataSource, nsIRDFPurgeableDataSource,
        !          1059:         nsIRDFRemoteDataSource</td>
        !          1060:         <td>Mostly used for adding, removing, and changing triples
        !          1061:         in a datasource. It provides the means to change the
        !          1062:         graph.</td>
        !          1063:       </tr>
        !          1064:       <tr>
        !          1065:         <td>nsIRDFNode, nsIRDFResource, nsIRDFLiteral</td>
        !          1066:         <td>Provide an equality function. Values for resources and
        !          1067:         literals can be retrieved. Objects of these types are
        !          1068:         retrieved from</td>
        !          1069:       </tr>
        !          1070:       <tr>
        !          1071:         <td>nsIRDFContainer</td>
        !          1072:         <td>Provides vector-like access to an RDF container's
        !          1073:         elements.</td>
        !          1074:       </tr>
        !          1075:       <tr>
        !          1076:         <td>nsIRDFContainerUtils</td>
        !          1077:         <td>Provides container creation and other container-related
        !          1078:         functions.</td>
        !          1079:       </tr>
        !          1080:       <tr>
        !          1081:         <td>nsIRDFObserver</td>
        !          1082:         <td>Fires events when data is changed in a datasource.</td>
        !          1083:       </tr>
        !          1084:       <tr>
        !          1085:         <td>nsIRDFXMLParser, nsIRDFXMLSerializer, nsIRDFXMLSink,
        !          1086:         nsIRDFXMLSource</td>
        !          1087:         <td>Used for working with RDF/XML. Functions are provided
        !          1088:         for parsing files and serializing content.</td>
        !          1089:       </tr>
        !          1090:     </table>
        !          1091:     <p>The sheer variety of RDF interfaces may seem overwhelming,
        !          1092:     but all interfaces serve different purposes and are often used
        !          1093:     in conjunction with one another. In your particular application
        !          1094:     space, you may find yourself using some subsets of these
        !          1095:     interfaces constantly and others not at all. This section
        !          1096:     describes some of the most commonly used functions. You can
        !          1097:     look up all of interfaces in their entirety 
        !          1098:     <!--INDEX web sites:RDF interfaces --> at <i><a href=
        !          1099:     "http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/">http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/</a></i>.</p>
        !          1100:     <h3><a name="77084"></a> nsIRDFService</h3>
        !          1101:     <p>If you <!--INDEX nsIRDFService interface --> 
        !          1102:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFService -->
        !          1103:     <!--INDEX interfaces:RDF:nsIRDFService --> will do any sort of
        !          1104:     RDF processing, you need to use the <i>nsIRDFService</i>
        !          1105:     interface. It provides the basics for working with datasources,
        !          1106:     resources, and literals, and is useful when you process RDF
        !          1107:     data. <i>nsIRDFService</i> can be initialized by using the
        !          1108:     <tt>getService</tt> method of the <tt>rdf-service</tt>
        !          1109:     class:</p>
        !          1110: <pre>
        !          1111: RDF = Components.<a href=
        !          1112: "MAILTO:classes[`@mozilla.org/rdf/rdf-service;1">classes[`@mozilla.org/rdf/rdf-service;1</a>']
        !          1113: getService(Components.interfaces.nsIRDFService);
        !          1114: </pre>
        !          1115:     <p>Once the service is available, it's ready to go to work.
        !          1116:     Even though no datasource is created yet (in this particular
        !          1117:     example), the RDF service can still get resources and literals,
        !          1118:     as shown in the next section.</p>
        !          1119:     <h4><a name="77085"></a> Getting a resource</h4>
        !          1120:     <p>Once a resource 
        !          1121:     <!--INDEX resources:nsIRDFService interface --> is created
        !          1122:     (e.g., with the identifier <tt>urn:root</tt> in <a href=
        !          1123:     "#77038">Example 10-7</a>), it needs to be added to a
        !          1124:     datasource:</p>
        !          1125: <pre>
        !          1126: rootResource = RDF.GetResource('urn:root');
        !          1127: </pre>
        !          1128:     <p>When a resource is already registered under the given
        !          1129:     identifier (see <a href="#77088">"Registering and unregistering
        !          1130:     datasources</a>," later in this chapter for more information
        !          1131:     about RDF registration), then <tt>
        !          1132:     <!--INDEX GetResource function --> GetResource</tt> returns
        !          1133:     that resource.</p>
        !          1134:     <h4><a name="77086"></a> Getting an anonymous resource</h4>
        !          1135:     <p>Anonymous resources are resources with no resource
        !          1136:     identifier. Here is the creation of a new anonymous resource
        !          1137:     and a test of its anonymity:</p>
        !          1138: <pre>
        !          1139: anonResource = RDF.GetAnonymousResource( );
1.1       david    1140: // This would be true. Checking is not necessary, just here for example.
1.9     ! petejc   1141: isAnon = RDF.isAnonymousResource(anonResource);
        !          1142: </pre>
        !          1143:     <p>Typically, these resources are turned into containers, as
        !          1144:     shown in the next section. Anonymous resources exist when names
        !          1145:     are not needed and a simple reference to that resource is all
        !          1146:     that is required.</p>
        !          1147:     <h4><a name="77087"></a> Getting a literal</h4>
        !          1148:     <p>The <tt><!--INDEX GetLiteral function --> GetLiteral</tt>
        !          1149:     function <!--INDEX literals:nsIRDFService interface --> returns
        !          1150:     the given name in the format of a literal, which you can then
        !          1151:     use to assert into an RDF graph as a resource.</p>
        !          1152: <pre>
        !          1153: myName = RDF.GetLiteral('Eric');
        !          1154: </pre>
        !          1155:     <p>Variations on this function are <tt>GetIntLiteral</tt> and
        !          1156:     <tt>GetDateLiteral</tt>.</p>
        !          1157:     <h4><a name="77088"></a> Registering and unregistering
        !          1158:     datasources</h4>
        !          1159:     <p>If you create <!--INDEX datasources:registering --> 
        !          1160:     <!--INDEX registering:datasources --> 
        !          1161:     <!--INDEX RDF (Resource Description 
        !          1162:     Framework):datasources, registering --> a Mozilla application
        !          1163:     that uses the same datasource or RDF resources in different
        !          1164:     ways, you may want to register the datasource with Mozilla.
        !          1165:     When you register a datasource, you register it as a component
        !          1166:     in Mozilla (see <a href="ch08.html#77062">"Component Manager"
        !          1167:     in Chapter 8</a> for more information on Mozilla's component
        !          1168:     model), which means it can be accessed and used as easily as
        !          1169:     any other XPCOM component, and from anywhere in Mozilla.</p>
        !          1170:     <p>To register a datasource, call the <tt>
        !          1171:     <!--INDEX RegisterDatasource method --> RegisterDatasource</tt>
        !          1172:     method of the RDF Service. In this example, the datasource
        !          1173:     already exists and is assigned to a variable named
        !          1174:     <i>myDatasource</i>:</p>
        !          1175: <pre>
        !          1176: RDF.RegisterDataSource(myDatasource, false);
        !          1177: </pre>
        !          1178:     <p>In this case, <i>myDatasource</i> is the datasource name,
        !          1179:     and the <tt>false</tt> parameter specifies that this datasource
        !          1180:     is not replacing a datasource with the same name. Once a
        !          1181:     datasource is registered with the component manager in this
        !          1182:     way, it can be retrieved by name and associated with another
        !          1183:     instance:</p>
        !          1184: <pre>
        !          1185: secondDatasource = anotherRDF.GetDataSource("My Datasource");
        !          1186: </pre>
        !          1187:     <p>To unregister a datasource from the RDF Service, pass the
        !          1188:     datasource into the <tt>UnRegisterDataSource</tt> function:</p>
        !          1189: <pre>
        !          1190: RDF.UnRegisterDataSource(myDatasource);
        !          1191: </pre>
        !          1192:     <p>Once it's unregistered, a datasource is no longer available
        !          1193:     to other instances of the RDF Service. Registered resources
        !          1194:     work the same way as datasources in the RDF Service: if a
        !          1195:     resource is registered with the RDF Service, then it is
        !          1196:     available in every instance of RDF Service. To get two
        !          1197:     different instances of the same registered datasource and
        !          1198:     unregister its use:</p>
        !          1199: <pre>
        !          1200: newResource = RDF.GetResource('my.resource');
1.1       david    1201: RDF.RegisterResource(newResource,false);
                   1202: notNewResource = RDF.GetResource('my.resource');
1.9     ! petejc   1203: RDF.UnRegisterResource(notNewResource);
        !          1204: </pre>
        !          1205:     <blockquote>
        !          1206:       <div class="c21">
        !          1207:         NOTE
        !          1208:       </div>
        !          1209:       <p>If you register resources and datasources, be sure to use
        !          1210:       the <i>overwrite</i> Boolean variable on
        !          1211:       <tt>RegisterDataSource</tt> and <tt>RegisterResource</tt> to
        !          1212:       avoid overwriting existing datasources.</p>
        !          1213:     </blockquote>
        !          1214:     <h4><a name="77089"></a> Getting a remote datasource</h4>
        !          1215:     <p>Finally, <i>nsIRDFService</i> provides 
        !          1216:     <!--INDEX datasources:remote, getting --> 
        !          1217:     <!--INDEX remote datasources, getting --> a useful method that
        !          1218:     loads a datasource from a remote server, which is a process
        !          1219:     that occurs asynchronously. Compared to forthcoming discussions
        !          1220:     about datasource loading, <tt>GetDataSource</tt> is a real
        !          1221:     shortcut:</p>
        !          1222: <pre>
        !          1223: remoteDatasource = RDF.GetDataSource('<a href=
        !          1224: "http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</a>');
        !          1225: </pre>
        !          1226:     <blockquote>
        !          1227:       <div class="c21">
        !          1228:         NOTE
        !          1229:       </div>
        !          1230:       <p>Remember that RDF files requested in this way must be set
        !          1231:       with the text/rdf MIME type on the web server to load
        !          1232:       properly.</p>
        !          1233:     </blockquote>
        !          1234:     <h3><a name="77090"></a> nsIRDFCompositeDataSource</h3>
        !          1235:     <p>When you work 
        !          1236:     <!--INDEX nsIRDFCompositeDataSource interface --> 
        !          1237:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFCompositeDataSource -->
        !          1238:     <!--INDEX interfaces:RDF:nsIRDFCompositeDataSource --> with
        !          1239:     multiple datasources, you can make things easier by grouping
        !          1240:     them, which <i>nsIRDFCompositeDataSource</i> allows you to do.
        !          1241:     This functionality aggregates data in a number of Mozilla's
        !          1242:     applications. To get this interface, invoke:</p>
        !          1243: <pre>
        !          1244: composite_datasource
1.1       david    1245: = '@mozilla.org/rdf/datasource;1?name=composite-datasource';
                   1246: compDataSource = Components.classes[composite_datasource]
1.9     ! petejc   1247: getService(Components.interfaces.nsIRDFCompositeDataSource);
        !          1248: </pre>
        !          1249:     <p>Once you have the interface, adding and removing datasources
        !          1250:     from the composite is easy. You can also enumerate the
        !          1251:     datasources by using the <tt>getNext</tt> method. <a href=
        !          1252:     "#77040">Example 10-8</a> demonstrates how to add, remove, and
        !          1253:     cycle through datasources.</p>
        !          1254:     <p><i>Example 10-8: <a name="77040"></a></i> <i>Manipulating
        !          1255:     datasources</i></p>
        !          1256: <pre>
        !          1257:  compDataSource.AddDataSource(datasource1);
1.1       david    1258:  compDataSource.AddDataSource(datasource2);
                   1259:  compDataSource.AddDataSource(datasource3);
                   1260:  compDataSource.RemoveDataSource(datasource1);
                   1261:  allDataSources = compDataSource.GetDataSources( );
                   1262:  datasource2 = allDataSources.getNext( );
                   1263:  datasource2.QueryInterface(Components.interfaces.nsIRDFDataSource);
                   1264:  datasource3 = allDataSources.getNext( );
1.9     ! petejc   1265:  datasource3.QueryInterface(Components.interfaces.nsIRDFDataSource);
        !          1266: </pre>
        !          1267:     <p>In <a href="#77040">Example 10-8</a>,
        !          1268:     <tt>allDataSources</tt> is an <i>nsISimpleEnumerator</i>
        !          1269:     returned by the <tt>GetDataSources</tt> method on the composite
        !          1270:     datasource. <tt>datasource1</tt> is removed from the composite,
        !          1271:     and then the remaining datasources are cycled through. This
        !          1272:     step provides a way to iterate through a collection of
        !          1273:     datasources. <i>nsIRDFCompositeDatasource</i> also inherits the
        !          1274:     many functions of <i>nsIRDFDataSource</i>; refer to the section
        !          1275:     <a href="#77091">"nsIRDFDataSource</a>" for more
        !          1276:     information.</p>
        !          1277:     <h3><a name="77091"></a> nsIRDFDataSource</h3>
        !          1278:     <p>The <i><!--INDEX nsIRDFDataSource interface --> 
        !          1279:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFDataSource -->
        !          1280:     <!--INDEX interfaces:RDF:nsIRDFDataSource -->
        !          1281:     nsIRDFDataSource</i> interface is large, with twenty functions
        !          1282:     and one attribute (<tt>URI</tt>), so it's one of the most
        !          1283:     common interfaces used to manipulate RDF data.
        !          1284:     <i>nsIRDFDataSource</i> contains all the components in <a href=
        !          1285:     "#77036">Example 10-6</a> with "datasource" in their contract
        !          1286:     IDs, along with other common components:</p>
        !          1287: <pre>
        !          1288: @mozilla.org/browser/bookmarks-service;1
1.1       david    1289: @mozilla.org/related-links-handler;1
                   1290: @mozilla.org/browser/localsearch-service;1
                   1291: @mozilla.org/registry-viewer;1
1.9     ! petejc   1292: @mozilla.org/browser/global-history;1
        !          1293: </pre>
        !          1294:     <p>The <i>nsIRDFDataSource</i> interface is meant to handle
        !          1295:     some of the core interaction with the datasource. APIs such as
        !          1296:     <tt>URI</tt>, <tt>GetTarget</tt>, <tt>Assert</tt>, and
        !          1297:     <tt>Change</tt> are helpful for working on the RDF graph
        !          1298:     itself. For example, the
        !          1299:     <tt>@mozilla.org/rdf/datasource;1?name=in-memory-datasource</tt>
        !          1300:     RDF component demonstrates the use of the
        !          1301:     <i>nsIRDFDataSource</i> interface. When this component is
        !          1302:     created, it's a blank datasource in memory, into which objects
        !          1303:     are inserted, changed, and removed. You can access the
        !          1304:     <i>nsIRDFDataSource</i> interface from the RDF component by
        !          1305:     first constructing an RDF graph in the in-memory
        !          1306:     datasource:</p>
        !          1307: <pre>
        !          1308: mem = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
1.1       david    1309: datasource = Components.classes[mem].
1.9     ! petejc   1310: createInstance(Components.interfaces.nsIRDFDataSource);
        !          1311: </pre>
        !          1312:     <p>Of the twenty functions (found at <i><a href=
        !          1313:     "http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl">
        !          1314:     http://lxr.mozilla.org/seamonkey/source/rdf/base/idl/nsIRDFDataSource.idl</a></i>)
        !          1315:     in this interface, we show only a handful here:</p>
        !          1316:     <ul>
        !          1317:       <li>Assertion and removal</li>
        !          1318:       <li>Changing values</li>
        !          1319:       <li>Moving triples</li>
        !          1320:       <li>HasAssertion</li>
        !          1321:       <li>GetTarget</li>
        !          1322:       <li>GetSource</li>
        !          1323:     </ul>
        !          1324:     <p>The main purpose of the <i>nsIRDFDatasource</i> interface is
        !          1325:     to work with RDF triples inside a datasource, allowing you to
        !          1326:     change that datasource's RDF graph.</p>
        !          1327:     <h4><a name="77092"></a> Assertion and removal</h4>
        !          1328:     <p>Recall from the 
        !          1329:     <!--INDEX triples:nsIRDFDataSource interface --> <a href=
        !          1330:     "#77065">"RDF triples: subject, predicate, and object</a>"
        !          1331:     section, earlier in this chapter, that triples are RDF
        !          1332:     statements in which the relationship between the subject,
        !          1333:     predicate, and object is more strictly defined. In the
        !          1334:     interface code, a triple's elements are all typically defined
        !          1335:     as resources rather than plain URIs, which means they can be
        !          1336:     asserted into a datasource in the particular sequence that
        !          1337:     makes them meaningful as parts of a triple:</p>
        !          1338: <pre>
        !          1339: rootSubject = RDF.GetResource('urn:root');
        !          1340: predicate = RDF.GetResource('<a href=
        !          1341: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
1.1       david    1342: object = RDF.GetResource('Chapter1');
1.9     ! petejc   1343: datasource.Assert(rootSubject,predicate,object,true);
        !          1344: </pre>
        !          1345:     <p>Once you assert the statement's elements into the datasource
        !          1346:     in this way, the datasource contains the triple. The
        !          1347:     <tt>truth</tt> value parameter in the last slot indicates that
        !          1348:     the given node is "locked" and thus cannot be overwritten.</p>
        !          1349:     <p>Removing a triple from the datasource is as easy as adding
        !          1350:     it. If you try to remove a triple that doesn't exist, your
        !          1351:     request is ignored and no error messages are raised. To
        !          1352:     unassert a triple in the datasource, use:</p>
        !          1353: <pre>
        !          1354: rootSubject = RDF.GetResource('urn:root');
        !          1355: predicate = RDF.GetResource('<a href=
        !          1356: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
1.1       david    1357: object = RDF.GetResource('Chapter8');
1.9     ! petejc   1358: datasource.Unassert(rootSubject,predicate,object);
        !          1359: </pre>
        !          1360:     <h4><a name="77093"></a> Changing values</h4>
        !          1361:     <p>Changing values <!--INDEX literals:values, changing --> 
        !          1362:     <!--INDEX datasources:values, changing --> in a datasource is
        !          1363:     also very easy. Assert and change a literal in the datasource
        !          1364:     as follows:</p>
        !          1365: <pre>
        !          1366: subject = RDF.GetResource('Chapter1');
        !          1367: predicate = RDF.GetResource('<a href=
        !          1368: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#title');
1.1       david    1369: object = RDF.GetLiteral('Mozilla as a Platform');
                   1370: datasource.Assert(subject,predicate,object,true);
                   1371: newObject = RDF.GetLiteral('Mozilla is a cool Platform!');
1.9     ! petejc   1372: datasource.Change(subject,predicate,newObject,);
        !          1373: </pre>
        !          1374:     <p>If working with triples seems hard in the template
        !          1375:     generation, their use in these examples-where adding to and
        !          1376:     changing the parts is so easy-may make things clearer.</p>
        !          1377:     <h4><a name="77094"></a> Moving triples</h4>
        !          1378:     <p>Moving a triple <!--INDEX triples:moving --> in a datasource
        !          1379:     also requires some simple code. This example moves the asserted
        !          1380:     triple in the previous section:</p>
        !          1381: <pre>
        !          1382: newSubject = RDF.GetResource('Chapter99');
1.1       david    1383: // Moving from Chapter1 to Chapter99
1.9     ! petejc   1384: datasource.Move(subject,newSubject,predicate,object);
        !          1385: </pre>
        !          1386:     <h4><a name="77095"></a> HasAssertion</h4>
        !          1387:     <p>This next example <!--INDEX HasAssertion function --> checks
        !          1388:     if the previous statement still exists in the datasource.</p>
        !          1389: <pre>
        !          1390: datasource.HasAssertion(newSubject,predicate,object,true);
        !          1391: </pre>
        !          1392:     <p>This function is useful when you create new statements and
        !          1393:     resources and want to make sure you are not overwriting
        !          1394:     pre-existing resources.</p>
        !          1395:     <h4><a name="77096"></a> GetTarget</h4>
        !          1396:     <p>The <tt><!--INDEX GetTarget method --> GetTarget</tt> method
        !          1397:     returns the resource's property value (i.e., the object). Given
        !          1398:     the RDF statement "(Eric) wrote (a book)," for example, the
        !          1399:     <tt>GetTarget</tt> method would input "Eric" and "wrote" and
        !          1400:     get back the object "a book." Once again, the example code is
        !          1401:     based on the previous examples:</p>
        !          1402: <pre>
        !          1403: object = datasource.GetTarget(newSubject,predicate,true);
1.1       david    1404: objects = datasource.GetTargets(rootSubject,predicate,true);
1.9     ! petejc   1405: // objects is an nsIEnumeration of the object and its properties
        !          1406: </pre>
        !          1407:     <p>In addition to <tt>GetTarget</tt>, as seen above, a
        !          1408:     <tt>GetTargets</tt> function returns an object and its
        !          1409:     properties in an enumeration. This function can be very handy
        !          1410:     for quick access to resources with fewer function calls.</p>
        !          1411:     <h4><a name="77097"></a> GetSource</h4>
        !          1412:     <p><tt><!--INDEX GetSource method --> GetSource</tt> is the
        !          1413:     inverse of <tt>GetTarget</tt>. Whereas <tt>GetTarget</tt>
        !          1414:     returns an object, <tt>GetSource</tt> returns the subject
        !          1415:     attached to an object. Given the RDF statement "(Eric) wrote (a
        !          1416:     book)" again, in other words, the <tt>GetSource</tt> method
        !          1417:     would input "wrote" and "a book" and get back the statement
        !          1418:     subject "Eric."</p>
        !          1419: <pre>
        !          1420: subject = datasource.GetSource(object,predicate,true);
1.1       david    1421: subjects = datasource.GetSources(object,predicate,true);
1.9     ! petejc   1422: // subjects is an nsIEnumeration of the subject and its properties
        !          1423: </pre>
        !          1424:     <p>When you create RDF statements with assertions or work with
        !          1425:     in-memory datasources, it is often difficult to remember the
        !          1426:     shape of the graph, which statements exist about which
        !          1427:     resources, or which objects are attached to which subjects.
        !          1428:     These "getter" methods can help you verify the shape of your
        !          1429:     graph.</p>
        !          1430:     <h3><a name="77098"></a> nsIRDFRemoteDataSource</h3>
        !          1431:     <p>The <!--INDEX nsIRDFRemoteDataSource interface --> 
        !          1432:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFRemoteDataSource -->
        !          1433:     <!--INDEX interfaces:RDF:nsIRDFRemoteDataSource --> <a href=
        !          1434:     "#77084">"nsIRDFService</a>" section (earlier in this chapter)
        !          1435:     showed how to load a datasource from a remote server simply. If
        !          1436:     you want control over that datasource, you can manage it by
        !          1437:     using the <i>nsIRDFRemoteDatasource</i> to set up a remote
        !          1438:     datasource:</p>
        !          1439: <pre>
        !          1440: xml = '@mozilla.org/rdf/datasource;1?name=xml-datasource';
1.1       david    1441: datasource = Components.classes[xml].
                   1442: createInstance(Components.interfaces.nsIRDFRemoteDataSource);
1.9     ! petejc   1443: datasource.Init('<a href=
        !          1444: "http://books.mozdev.org/file.rdf">http://books.mozdev.org/file.rdf</a>');
        !          1445: datasource.Refresh(false);
        !          1446: </pre>
        !          1447:     <p>In this example, the <tt>Init</tt> and <tt>Refresh</tt>
        !          1448:     methods control the datasource on the server. In addition to
        !          1449:     these methods, you can call the <tt>Flush</tt> method to flush
        !          1450:     the data that's been changed and reload, or you can check
        !          1451:     whether the datasource is loaded by using the <tt>loaded</tt>
        !          1452:     property:</p>
        !          1453: <pre>
        !          1454: if (datasource.loaded) {
1.1       david    1455: // Do something
1.9     ! petejc   1456: }
        !          1457: </pre>
        !          1458:     <p>Built-in datasources that implement
        !          1459:     <i>nsIRDFRemoteDataSource</i> (and other necessary interfaces)
        !          1460:     and do their own data handling include:</p>
        !          1461: <pre>
        !          1462: @mozilla.org/rdf/datasource;1?name=history
1.1       david    1463: @mozilla.org/browser/bookmarks-service;1
                   1464: @mozilla.org/autocompleteSession;1?type=history
                   1465: @mozilla.org/browser/global-history;1
1.9     ! petejc   1466: @mozilla.org/rdf/datasource;1?name=bookmarks
        !          1467: </pre>
        !          1468:     <h3><a name="77099"></a> nsIRDFPurgeableDataSource</h3>
        !          1469:     <p>Using <!--INDEX nsIRDFPurgeableDataSource interface --> 
        !          1470:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFPurgeableDataSource -->
        !          1471:     <!--INDEX interfaces:RDF:nsIRDFPurgeableDataSource --> the
        !          1472:     <i>nsIRDFPurgeableDatasource</i> interface allows you to delete
        !          1473:     a whole section of an existing in-memory datasource in one fell
        !          1474:     swoop. This means that all relatives-all statements derived
        !          1475:     from that node-are removed. When you work with large in-memory
        !          1476:     datasources (such as email systems), the using interface can
        !          1477:     manipulate the data efficiently. The <tt>Sweep( )</tt> method
        !          1478:     can delete a section that is marked in the datasource.</p>
        !          1479: <pre>
        !          1480: datasource.
1.1       david    1481: QueryInterface(Components.interfaces.nsIRDFPurgeableDataSource);
                   1482: rootSubject = RDF.GetResource('urn:root');
1.9     ! petejc   1483: predicate = RDF.GetResource('<a href=
        !          1484: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#chapters');
1.1       david    1485: object = RDF.GetResource('Chapter1');
                   1486: datasource.Mark(rootSubject,predicate,object,true);
1.9     ! petejc   1487: datasource.Sweep( );
        !          1488: </pre>
        !          1489:     <p>In this instance, a statement about a chapter in a book is
        !          1490:     marked and then removed from the datasource. You can also mark
        !          1491:     more than one node before sweeping.</p>
        !          1492:     <h3><a name="77100"></a> nsIRDFNode, nsIRDFResource, and
        !          1493:     nsIRDFLiteral</h3>
        !          1494:     <p>These types of objects come from only a few different
        !          1495:     places. Here are all the functions that can return the resource
        !          1496:     of a literal:</p>
        !          1497: <pre>
        !          1498: nsIRDFService.GetResource
1.1       david    1499: nsIRDFService.GetAnonymousResource
                   1500: nsIRDFService.GetLiteral
                   1501: nsIRDFDataSource.GetSource
1.9     ! petejc   1502: nsIRDFDataSource.GetTarget
        !          1503: </pre>
        !          1504:     <p><i>nsIRDFNode <!--INDEX nsIRDFNode interface --> 
        !          1505:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFNode -->
        !          1506:     <!--INDEX interfaces:RDF:nsIRDFNode --></i> is the parent of
        !          1507:     <i>nsIRDFResource</i> and <i>nsIRDFLiteral</i>. It is not used
        !          1508:     often because it's sole function is to test equality:</p>
        !          1509: <pre>
        !          1510: isEqual = resource1.EqualsNode(resource2);
        !          1511: </pre>
        !          1512:     <p>The other two interfaces inherit this function
        !          1513:     automatically. <tt>EqualsNode</tt> tests the equivalency of two
        !          1514:     resources, which can be useful when you try to put together
        !          1515:     different statements (e.g., "Eric wrote a book" and "[This]
        !          1516:     book is about XML") and want to verify that a resource like
        !          1517:     "book" is the same in both cases.</p>
        !          1518:     <h4><a name="77101"></a> nsIRDFResource</h4>
        !          1519:     <p>Like <!--INDEX nsIRDFResource interface --> 
        !          1520:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFResource -->
        !          1521:     <!--INDEX interfaces:RDF:nsIRDFResource --> <i>nsIRDFNode</i>,
        !          1522:     <i>nsIRDFResource</i> is a minimalist interface. Here are the
        !          1523:     functions and the property available in a resource from the
        !          1524:     <i>nsIRDFResource</i> interface:</p>
        !          1525: <pre>
        !          1526: resource = RDF.GetAnonymousResource( );
1.1       david    1527: // get the resource value, something like 'rdf:#$44RG7'
                   1528: resourceIdentifierString = resource.Value;
                   1529: // compare the resource to an identifier
                   1530: isTrue = resourceEqualsString(resourceIdentifierString);
                   1531: // Give the resource a real name.
1.9     ! petejc   1532: resource.Init('Eric');
        !          1533: </pre>
        !          1534:     <h4><a name="77102"></a> nsIRDFLiteral</h4>
        !          1535:     <p>A literal's <!--INDEX nsIRDFLiteral interface --> 
        !          1536:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFLiteral -->
        !          1537:     <!--INDEX interfaces:RDF:nsIRDFLiteral --> value can be read
        !          1538:     but not written. To change the value of a literal, make a new
        !          1539:     literal and set it properly:</p>
        !          1540: <pre>
        !          1541: aValue = literal.Value;
        !          1542: </pre>
        !          1543:     <p>Note that <tt>aValue</tt> could be a string or an integer in
        !          1544:     this case. The base type conversion, based on the data's
        !          1545:     format, is done automatically.</p>
        !          1546:     <h3><a name="77103"></a> nsIRDFContainerUtils</h3>
        !          1547:     <p>This interface <!--INDEX nsIRDFContainerUtils interface --> 
        !          1548:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainerUtils -->
        !          1549:     <!--INDEX interfaces:RDF:nsIRDFContainerUtils --> facilitates
        !          1550:     the creation of containers and provides other container-related
        !          1551:     functions. It provides functions that make and work with a
        !          1552:     <tt>sequence</tt>, <tt>bag</tt>, and <tt>alternative</tt>. (The
        !          1553:     functions work the same way for all types of containers, so
        !          1554:     only <tt>sequence</tt> is covered here.) To create an instance
        !          1555:     of <i>nsIRDFContainerUtils</i>, use the following:</p>
        !          1556: <pre>
        !          1557: containerUtils = Components.classes['@mozilla.org/rdf/container-utils;1'
        !          1558: getService(Components.interfaces.nsIRDFContainerUtils);
        !          1559: </pre>
        !          1560:     <p>Once you create an anonymous resource, you can create a
        !          1561:     sequence from it. Then you can test the type of the container
        !          1562:     and see whether it's empty:</p>
        !          1563: <pre>
        !          1564: // create an anonymous resource
1.1       david    1565: anonResource = RDF.GetAnonymousResource( );
                   1566: // create a sequence from that resource
                   1567: aSequence = containerUtils.MakeSeq(datasource,anonResource);
                   1568: // test the resource
                   1569: // (all of these are true)
                   1570: isContainer = containerUtils.isContainer(datasource,anonResource);
                   1571: isSequence = containerUtils.isSequence(datasource,anonResource);
1.9     ! petejc   1572: isEmpty = containerUtils.isEmpty(datasource,anonResource);
        !          1573: </pre>
        !          1574:     <p>Note that the sequence object is not passed into the
        !          1575:     functions performing the test in the previous example; the
        !          1576:     resource containing the sequence is passed in. Although
        !          1577:     <tt>aSequence</tt> and <tt>anonResource</tt> are basically the
        !          1578:     same resource, their data types are different.
        !          1579:     <tt>isContainer</tt>, <tt>isSequence</tt>, and <tt>isEmpty</tt>
        !          1580:     can be used more easily with other RDF functions when a
        !          1581:     resource is used as a parameter:</p>
        !          1582: <pre>
        !          1583: object = datasource.GetTarget(subject,predicate,true);
1.1       david    1584: if(RDF.isAnonymousResource(object))
                   1585: {
                   1586: isSeq = containerUtils.IsSeq(datasource,object);
1.9     ! petejc   1587: }
        !          1588: </pre>
        !          1589:     <p>The RDF container utilities also provide an indexing
        !          1590:     function. <tt>indexOf</tt> is useful for checking if an element
        !          1591:     exists in a container resource:</p>
        !          1592: <pre>
        !          1593: indexNumber =
1.1       david    1594: containerUtils.indexOf(datasource,object,RDF.GetLiteral('Eric'));
                   1595: if(index != -1)
1.9     ! petejc   1596: alert('Eric exists in this container');
        !          1597: </pre>
        !          1598:     <h3><a name="77104"></a> nsIRDFContainer</h3>
        !          1599:     <p>This interface <!--INDEX nsIRDFContainer interface --> 
        !          1600:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFContainer -->
        !          1601:     <!--INDEX interfaces:RDF:nsIRDFContainer --> provides
        !          1602:     vector-like access to an RDF container's elements.<a name=
        !          1603:     "b291"></a><a href="#291">[*]</a> The <i>nsIRDFContainer</i>
        !          1604:     interface allows you to add, look up, and remove elements from
        !          1605:     a container once you create it.</p>
        !          1606:     <h4><a name="77105"></a> Adding an element to a container</h4>
        !          1607:     <p>You can add an <!--INDEX containers:elements, adding --> 
        !          1608:     <!--INDEX elements:containers, adding to --> element to a
        !          1609:     container in two ways. You can append it to the end of the list
        !          1610:     with <tt>Append</tt> or insert it at a specific place in the
        !          1611:     container:</p>
        !          1612: <pre>
        !          1613: newLiteral = RDF.GetLiteral('Ian');
1.1       david    1614: aSequence.AppendElement(newLiteral);
                   1615: // or
1.9     ! petejc   1616: aSequence.InsertElementAt(newLiteral,3,true);
        !          1617: </pre>
        !          1618:     <p>The second attribute in <tt>InsertElementAt</tt> is where
        !          1619:     the element should be placed. The third attribute specifies
        !          1620:     that the list can be reordered. This method is useful for
        !          1621:     working with ordered containers such as sequences. If this
        !          1622:     locking parameter is set to false and an element already exists
        !          1623:     at that location, then the existing element is overwritten.</p>
        !          1624:     <h4><a name="77106"></a> Removing an element from a
        !          1625:     container</h4>
        !          1626:     <p>Removing an element from a container works much the same as
        !          1627:     adding one. The difference is that a reordering attribute is
        !          1628:     included on <tt>RemoveElement</tt>. If this attribute is set to
        !          1629:     false, you may have holes in the container, which can create
        !          1630:     problems when enumerating or indexing elements within.</p>
        !          1631: <pre>
        !          1632: newLiteral = RDF.GetLiteral('Ian');
1.1       david    1633: aSequence.RemoveElement(newLiteral,true);
                   1634: // or
1.9     ! petejc   1635: aSequence.RemoveElementAt(newLiteral,3,true);
        !          1636: </pre>
        !          1637:     <p>If you use the <tt>indexOf</tt> property of
        !          1638:     <tt>nsIRDFContainer</tt>, you can also use <tt>GetCount</tt> to
        !          1639:     learn how many elements are in the container. The count starts
        !          1640:     at 0 when the container is initialized:</p>
        !          1641: <pre>
        !          1642: numberOfElements = aSequence.GetCount( );
        !          1643: </pre>
        !          1644:     <p>Once you have the sequence, the datasource and resource the
        !          1645:     sequence resides in can be retrieved. In effect, these
        !          1646:     properties look outward instead of toward the data:</p>
        !          1647: <pre>
        !          1648: seqDatasource = aSequence.DataSource;
        !          1649: seqResource = aSequence.Resource;
        !          1650: </pre>
        !          1651:     <p>Like many methods in the RDF interfaces, this one allows you
        !          1652:     to traverse and retrieve any part of the RDF graph.</p>
        !          1653:     <h3><a name="77107"></a> nsIRDFXML Interfaces</h3>
        !          1654:     <p>The RDF/XML interfaces are covered only briefly here.
        !          1655:     Besides being abstract and confusing, these interfaces require
        !          1656:     a lot of error handling to work correctly. Fortunately, a
        !          1657:     library on mozdev.org called <i>JSLib</i> handles RDF file
        !          1658:     access. The <i>JSLib</i> XML library does the dirty work in a
        !          1659:     friendly manner. See the section <a href="#77112">"JSLib RDF
        !          1660:     Files</a>," later in this chapter, for more information.</p>
        !          1661:     <h4><a name="77108"></a> nsIRDFXMLParser and nsIRDFXMLSink</h4>
        !          1662:     <p><i>nsIRDFXML</i> <!--INDEX nsIRDFXMLParser interface --> 
        !          1663:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLParser -->
        !          1664:     <!--INDEX interfaces:RDF:nsIRDFXMLParser --> is the raw RDF/XML
        !          1665:     parser of Mozilla. Used by Mozilla, its main purpose is to
        !          1666:     parse an RDF file <!--INDEX parsing:RDF files -->
        !          1667:     asynchronously as a stream listener. Though this subject is
        !          1668:     beyond the scope of this book, the interface provides something
        !          1669:     interesting and useful. The <tt>parseString</tt> function
        !          1670:     allows you to feed <i>nsIRDFXMLParser</i> a string and have it
        !          1671:     parse that data as RDF and put it into a datasource, as <a
        !          1672:     href="#77042">Example 10-9</a> demonstrates.</p>
        !          1673:     <p><i>Example 10-9: <a name="77042"></a></i> <i>Parse an
        !          1674:     RDF/XML string into a datasource</i></p>
        !          1675: <pre>
        !          1676:  RDF = Components.classes&lt;/td&gt;['@mozilla.org/rdf/rdf-service;1'].
1.1       david    1677:          getService(Components.interfaces.nsIRDFService);
                   1678:  // Used to create a URI below
1.9     ! petejc   1679:  ios = Components.classes&lt;/td&gt;["@mozilla.org/network/io-service;1"].
1.1       david    1680:        getService(Components.interfaces.nsIIOService);
                   1681:  xmlParser = '@mozilla.org/rdf/xml-parser;1';
1.9     ! petejc   1682:  parser = Components.classes&lt;/td&gt;[xmlParser].
1.1       david    1683:           createInstance(Components.interfaces.nsIRDFXMLParser);
1.9     ! petejc   1684:  uri = ios.newURI("<a href=
        !          1685: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#", null);
1.1       david    1686:  // Entire RDF File stored in a string
                   1687:  rdfString =
1.9     ! petejc   1688:    '&lt;rdf:RDF xmlns:rdf=&lt;/td&gt;<i><a href=
        !          1689: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#</i>' +
        !          1690:    'xmlns:b="<a href=
        !          1691: "http://books.mozdev.org/rdf">http://books.mozdev.org/rdf</a>#"&gt;' +
1.1       david    1692:    '&lt;rdf:Description about="urn:root"&gt;' + // Rest of file ...
                   1693:  parser.parseString(datasource,uri,rdfString);
1.9     ! petejc   1694:  // Parsed string data now resides in the datasource
        !          1695: </pre>
        !          1696:     <p>The RDF/XML data that was in the string is a part of the
        !          1697:     datasource and ready for use (just like any other RDF data in a
        !          1698:     datasource). The <tt>uri</tt> acts as a base reference for the
        !          1699:     RDF in case of relative links.</p>
        !          1700:     <p><i>nsIRDFXMLParser</i> uses <i>nsIRDFXMLSink</i> 
        !          1701:     <!--INDEX nsIRDFXMLSink interface --> 
        !          1702:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSink -->
        !          1703:     <!--INDEX interfaces:RDF:nsIRDFXMLsink --> for event 
        !          1704:     <!--INDEX event handling:RDF files --> handling. The interfaces
        !          1705:     are totally separate, but behind the scenes, they work together
        !          1706:     with the incoming data. <a href="#77044">Example 10-10</a>
        !          1707:     shows how a series of events is created in an object and then
        !          1708:     used to handle parser events. Example 10-10<a name="77044"></a>
        !          1709:     <i>Setup nsIRDFXMLSink with event handlers</i></p>
        !          1710: <pre>
        !          1711:  var Observer = {
1.1       david    1712:     onBeginLoad: function(aSink)
                   1713:     {
                   1714:       alert("Beginning to load the RDF/XML...");
                   1715:     },
                   1716:     onInterrupt: function(aSink) {},
                   1717:     onResume: function(aSink) {},
                   1718:     onEndLoad: function(aSink)
                   1719:     {
                   1720:       doneLoading( ); // A function that does something with the datasource
                   1721:     },
                   1722:    onError: function(aSink, aStatus, aErrorMsg)
                   1723:    {
                   1724:      alert("Error: " + aErrorMsg);
                   1725:    }
1.9     ! petejc   1726:  };
        !          1727: </pre>
        !          1728:     <p>Once the event handlers are set up, you can use
        !          1729:     <i>nsIRDFXMLSink</i>:</p>
        !          1730: <pre>
        !          1731: sink = datasource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
        !          1732: sink.addXMLSinkObserver(observer);
        !          1733: </pre>
        !          1734:     <p>The events are then triggered automatically when the
        !          1735:     datasource is loaded up with data, allowing you to create
        !          1736:     handlers that manipulate the data as it appears.</p>
        !          1737:     <h4><a name="77109"></a> nsIRDFXMLSerializer and
        !          1738:     nsIRDFXMLSource</h4>
        !          1739:     <p>These two <!--INDEX nsIRDFXMLSerializer interface --> 
        !          1740:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSerializer -->
        !          1741:     <!--INDEX interfaces:RDF:nsIRDFXMLSerializer --> interfaces are
        !          1742:     meant to work together. <i>nsIRDFXMLSerializer</i> lets you
        !          1743:     <tt>init</tt> a datasource into the <tt>xml-serializer</tt>
        !          1744:     module that outputs RDF. However, <i>
        !          1745:     <!--INDEX nsIRDFXMLSource interface --> 
        !          1746:     <!--INDEX RDF (Resource Description Framework):interfaces:nsIRDFXMLSource -->
        !          1747:     <!--INDEX interfaces:RDF:nsIRDFXMLSource -->
        !          1748:     nsIRDFXMLSource</i> actually contains the <tt>Serialize</tt>
        !          1749:     function. Here's how to serialize a datasource into an
        !          1750:     alert:</p>
        !          1751: <pre>
        !          1752: serializer = '@mozilla.org/rdf/xml-serializer;1';
1.1       david    1753: s = Components.classes[serializer].
                   1754: createInstance(Components.interfaces.nsIRDFXMLSerializer);
                   1755: s.init(datasource);
                   1756: output = new Object( );
                   1757: output.write = new function(buf,count)
                   1758: {
                   1759: alert(buf); // Show the serialized syntax
                   1760: return count;
                   1761: }
1.9     ! petejc   1762: s.QueryInterface(Components.interfaces.nsIRDFXMLSource).Serialize(output);
        !          1763: </pre>
        !          1764:     <p>As in the previous example with <i>nsIRDFXMLParser</i>, <a
        !          1765:     href="#77044">Example 10-10</a> does not use RDF data from a
        !          1766:     file. The serialized data is passed directly to an alert, which
        !          1767:     then displays the generated RDF.</p>
        !          1768:     <h2><a name="77110"></a> Template Dynamics</h2>
        !          1769:     <p>Once you learn how to create templates and modify
        !          1770:     datasources, the ultimate in template mastery is to apply
        !          1771:     datasources to a template dynamically.</p>
        !          1772:     <p>This process is done through the <tt>database</tt> property
        !          1773:     of a XUL element that contains a template. The object returned
        !          1774:     by this property has only two methods, <tt>AddDataSource</tt>
        !          1775:     and <tt>RemoveDataSource</tt>. A separate
        !          1776:     <tt>builder.rebuild</tt> function is also available for
        !          1777:     refreshing the template's display, but you probably won't need
        !          1778:     it once the template automatically updates itself. The addition
        !          1779:     and removal of a datasource to a <tt>&lt;tree&gt;</tt> template
        !          1780:     is demonstrated here:</p>
        !          1781: <pre>
        !          1782: tree = document.getElementById('tree-template');
1.1       david    1783: tree.database.AddDataSource(someDatasource);
                   1784: // tree will now update its display to show contents
                   1785: tree.database.RemoveDataSource(someDatasource);
                   1786: // tree will now be empty
                   1787: // Optional, use only when tree is not updating for some reason
1.9     ! petejc   1788: tree.builder.rebuild( );
        !          1789: </pre>
        !          1790:     <p>You can add and remove any datasource as long as the
        !          1791:     template actually matches the data inside it. Also, multiple
        !          1792:     datasources can be applied to the same template with no
        !          1793:     problems, which allows you to aggregate data from different
        !          1794:     places, such as contact data, work information, and computer
        !          1795:     hardware information (e.g., "Eric uses a Compaq with the serial
        !          1796:     number 1223456-1091 to write his book and he sits on the fourth
        !          1797:     floor of the Acme Building, which is the Bay Area branch of
        !          1798:     Acme Enterprises.)</p>
        !          1799:     <h3><a name="77111"></a> Template Dynamics in XBL</h3>
        !          1800:     <p>Putting templates 
        !          1801:     <!--INDEX XBL (eXtensible Binding Language):templates --> 
        !          1802:     <!--INDEX templates:XBL --> <!--INDEX datasources:templates -->
        !          1803:     inside XBL can be a useful organizational scheme. Here is a
        !          1804:     basic implementation of a widget that creates a list of people
        !          1805:     based on names listed in an attribute:</p>
        !          1806: <pre>
        !          1807: &lt;people names="Brian King,Eric Murphy,Ian Oeschger,Pete Collins,David Boswell"/&gt;
        !          1808: </pre>
        !          1809:     <p>Obviously, the comma is used as the delimiter for this list.
        !          1810:     The constructor element in <a href="#77046">Example 10-11</a>
        !          1811:     uses JavaScript to break up this string. Example 10-11<a name=
        !          1812:     "77046"></a> <i>Binding with in-memory datasource and
        !          1813:     &lt;listbox&gt; template</i></p>
        !          1814: <pre>
        !          1815:  &lt;?xml version="1.0"?&gt;
        !          1816:  &lt;bindings xmlns ="<a href=
        !          1817: "http://www.mozilla.org/xbl">http://www.mozilla.org/xbl</a>"
        !          1818:  xmlns:xul="<a href=
        !          1819: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
1.1       david    1820:    &lt;binding id="people"&gt;
                   1821:      &lt;implementation&gt;
                   1822:        &lt;constructor&gt;
1.9     ! petejc   1823:        &lt;!&lt;/td&gt;[CDATA[
1.1       david    1824:          // Read the Names into an Array
1.9     ! petejc   1825:          names = document.getAnonymousNodes(this)&lt;/td&gt;[0].getAttribute('names');
1.1       david    1826:          names = new String(names);
                   1827:          namesArray= names.split(',');
                   1828:          // Initialize the RDF Service
                   1829:          rdf = Components
1.9     ! petejc   1830:               .classes&lt;/td&gt;['@mozilla.org/rdf/rdf-service;1']
1.1       david    1831:               .getService(Components.interfaces.nsIRDFService);
                   1832:          // Initialize a Datasource in Memory
                   1833:               inMemory = '@mozilla.org/rdf/datasource;1?name=in-memory-datasource';
1.9     ! petejc   1834:          datasource = Components.classes&lt;/td&gt;[inMemory].
1.1       david    1835:             createInstance(Components.interfaces.nsIRDFDataSource);
                   1836:          // Create the Root Node and an Anonymous Resource to Start With
                   1837:          root   = rdf.GetResource('urn:root');
                   1838:          people = rdf.GetAnonymousResource( );
                   1839:          // Insert the People resource into the RDF graph
                   1840:          datasource.Assert
                   1841:            (root,
1.9     ! petejc   1842:             rdf.GetResource('<a href=
        !          1843: "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#people'),
1.1       david    1844:             people,true);
                   1845:          // Initialize Methods needed for Containers
                   1846:          rdfc = Components
1.9     ! petejc   1847:                .classes&lt;/td&gt;['@mozilla.org/rdf/container-utils;1']
1.1       david    1848:                .getService(Components.interfaces.nsIRDFContainerUtils);
                   1849:          // For the People resource, make a Sequence of people
                   1850:          peopleSequence = rdfc.MakeSeq(datasource, people);
                   1851:          for(i=0;i&lt;namesArray.length;i++)
                   1852:          {
                   1853:            // Create a Person, with a Unique Number, for example
                   1854:            person = rdf.GetResource(i);
                   1855:            // Insert the Person's name into the RDF graph underneath number
                   1856:            datasource.Assert
                   1857:              (person,
1.9     ! petejc   1858:               rdf.GetResource('<a href=
        !          1859: "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#name'),
        !          1860:               rdf.GetLiteral(namesArray&lt;/td&gt;[i]),true);
1.1       david    1861:            peopleSequence.AppendElement(person);
                   1862:          }
1.9     ! petejc   1863:          list = document.getAnonymousNodes(this)&lt;/td&gt;[1];
1.1       david    1864:          list.database.AddDataSource(datasource);
                   1865:        ]]&gt;
                   1866:        &lt;/constructor&gt;
                   1867:      &lt;/implementation&gt;
                   1868:      &lt;content&gt;
                   1869:        &lt;xul:box id="names" inherits="names" flex="0"/&gt;
                   1870:        &lt;xul:listbox datasources="rdf:null" ref="urn:root" flex="1"&gt;
                   1871:          &lt;xul:template&gt;
                   1872:            &lt;xul:rule&gt;
                   1873:              &lt;xul:conditions&gt;
                   1874:                &lt;xul:content uri="?uri"/&gt;
                   1875:                &lt;xul:triple subject="?uri"
1.9     ! petejc   1876:                         predicate="<a href=
        !          1877: "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#people"                              object="?people"/&gt;
1.1       david    1878:                &lt;xul:member container="?people" child="?person"/&gt;
                   1879:                &lt;xul:triple subject="?person"
1.9     ! petejc   1880:                         predicate="<a href=
        !          1881: "http://www.mozdev.org/rdf">http://www.mozdev.org/rdf</a>#name"                         object="?name"/&gt;
1.1       david    1882:              &lt;/xul:conditions&gt;
                   1883:              &lt;xul:action&gt;
                   1884:                &lt;xul:listitem uri="?person"&gt;
                   1885:                  &lt;xul:listcell&gt;
                   1886:                    &lt;xul:description value="?person "/&gt;
                   1887:                    &lt;xul:description value="?name"/&gt;
                   1888:                  &lt;/xul:listcell&gt;
                   1889:                &lt;/xul:listitem&gt;
                   1890:              &lt;/xul:action&gt;
                   1891:            &lt;/xul:rule&gt;
                   1892:          &lt;/xul:template&gt;
                   1893:        &lt;/xul&gt;
                   1894:      &lt;/content&gt;
                   1895:    &lt;/binding&gt;
1.9     ! petejc   1896:  &lt;/bindings&gt;
        !          1897: </pre>
        !          1898:     <p>In <a href="#77046">Example 10-11</a>, everything you need
        !          1899:     to display a datasource dynamically is present. The only
        !          1900:     difference between this dynamically generated version and a
        !          1901:     static RDF-based template is the
        !          1902:     <tt>datasources="rdf:null"</tt>, which specifies that the
        !          1903:     template does not refer to an actual datasource. Data that is
        !          1904:     edited, rearranged, or changed in a different way is often
        !          1905:     displayed dynamically in the UI with templates in this
        !          1906:     manner.</p>
        !          1907:     <h2><a name="77112"></a> JSLib RDF Files</h2>
        !          1908:     <p>Working 
        !          1909:     <!--INDEX STARTRANGE==RDF (Resource Description Framework):files:JSLib -->
        !          1910:     <!--INDEX STARTRANGE==JSLib libraries:RDF files --> 
        !          1911:     <!--INDEX STARTRANGE==files:RDF:JSLib --> with actual RDF files
        !          1912:     is not easy. However, JSLib (<i><a href=
        !          1913:     "http://jslib.mozdev.org">http://jslib.mozdev.org</a></i>)
        !          1914:     provides an RDF file library that can help you develop an
        !          1915:     RDF-based application. The library provides many types of error
        !          1916:     checking, as well as a friendly abstraction away from the
        !          1917:     RDF/XML interfaces of Mozilla (see <a href="#77107">"nsIRDFXML
        !          1918:     Interfaces</a>," later in this chapter). <a href=
        !          1919:     "#77048">Example 10-12</a> shows some common uses of the
        !          1920:     <tt>RDFFile</tt> class in JSLib. This functionality can be used
        !          1921:     in situations in which you have data in RDF that you want to
        !          1922:     pull out "manually" and use piece by piece (rather than as a
        !          1923:     whole datasource in a template). Example 10-12<a name=
        !          1924:     "77048"></a> <i>Creating and modifying an RDF file using
        !          1925:     JSLib</i></p>
        !          1926: <pre>
        !          1927:  var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
1.1       david    1928:  var gTreeBody = null;
                   1929:  var gListbox = null;
                   1930:  var gRDF = null;
                   1931:  function onload( )
                   1932:  {
                   1933:    fileUtils = new FileUtils( );
                   1934:    path = fileUtils.chrome_to_path(rdfFileURL);
                   1935:    if(navigator.platform == "Win32") {
                   1936:      path = path.replace(/\//g,"\\");
                   1937:      // Only needed on Windows, until JSLib is fixed
                   1938:    }
1.9     ! petejc   1939:    gRDF = new RDFFile(path,'jar:flies','<a href=
        !          1940: "http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</a>#');
1.1       david    1941:    gTreeBody = document.getElementById('tb');
                   1942:    gTreeBody.database.AddDataSource(gRDF.dsource);
                   1943:    gListbox  = document.getElementById('list');
                   1944:    gListbox.database.AddDataSource(gRDF.dsource);
                   1945:    rebuildLists( );
                   1946:  }
                   1947:  function rebuildLists( )
                   1948:  {
                   1949:    gTreeBody.builder.rebuild( );
                   1950:    gListbox.builder.rebuild( );
                   1951:  }
                   1952:  function update( )
                   1953:  {
                   1954:    name      = document.getElementById('nameField').value;
                   1955:    color     = document.getElementById('colorField').value;
                   1956:    quantity  = document.getElementById('quantityField').value;
                   1957:    seqNumber = -1;
                   1958:    del       = false;
                   1959:    replace   = false;
                   1960:    if(document.getElementById('delete').checked)
                   1961:      del = true;
                   1962:    if(document.getElementById('replace').checked)
                   1963:      replace = true;
                   1964:    var seqLength = 0;
                   1965:    if(gRDF.doesSeqExist('types'))
                   1966:    {
                   1967:      seqLength = gRDF.getSeqSubNodes('types').length;
                   1968:      //if(del)gRDF.removeSeq('types',false);
                   1969:    }
                   1970:    else
                   1971:      gRDF.addSeq('types');
                   1972:    for(i=0;i&lt;seqLength;i++)
                   1973:    {
                   1974:      tempItem = 'types:_' + (i+1);
                   1975:      if(gRDF.getAttribute(tempItem,'name')==name)
                   1976:        seqNumber = gRDF.getAttribute(tempItem,'number');
                   1977:    }
                   1978:    if(seqNumber == -1)
                   1979:    {
                   1980:      item = 'types:_' + (seqLength+1);
                   1981:      gRDF.setAttribute(item,'name',name);
                   1982:      gRDF.setAttribute(item,'number',seqLength+1);
                   1983:    }
                   1984:    else
                   1985:    {
                   1986:      item = 'types:_' + seqNumber;
                   1987:      gRDF.setAttribute(item,'number',seqNumber);
                   1988:    }
                   1989:    if(color!='')
                   1990:      gRDF.setAttribute(item,'color',color);
                   1991:    if(quantity!='')
                   1992:    {
                   1993:      gRDF.setAttribute(item,'quantity',quantity);
                   1994:      gRDF.setAttribute(item,'dead',calcDead(quantity,replace));
                   1995:    }
                   1996:    if(!del)
                   1997:      gRDF.addNode(item);
                   1998:    else
                   1999:      gRDF.removeNode(item);
                   2000:    gRDF.flush( );
                   2001:    onload( );
                   2002:  }
                   2003:  function calcDead(quantity,replace)
                   2004:  {
                   2005:    if(!replace)
                   2006:    {
                   2007:      v = parseInt( (quantity * Math.random( )) * 0.13 );
                   2008:      return (v.toString( ));
                   2009:    }
                   2010:    else
                   2011:      return 0;
                   2012:  }
                   2013:  function changeC(color)
                   2014:  {
                   2015:    document.getElementById('colorField').value=color;
                   2016:  }
                   2017:  function changeQ(quantity)
                   2018:  {
                   2019:    document.getElementById('quantityField').value=quantity;
1.9     ! petejc   2020:  }
        !          2021: </pre>
        !          2022:     <p>This example contains a datasource that represents a
        !          2023:     collection of flies. These flies are built up dynamically with
        !          2024:     JavaScript objects from the RDF library, which represent the
        !          2025:     datasource itself (<tt>gRDF = new RDFFile</tt>), methods that
        !          2026:     view and update the data
        !          2027:     (<tt>if(gRDF.getAttribute(tempItem,'name')==name</tt>), and
        !          2028:     utilities that make work with RDF files easier (<tt>path =
        !          2029:     fileUtils.chrome_to_path(rdfFileURL)</tt>).</p>
        !          2030:     <p><a href="#77050">Example 10-13</a> initializes and updates a
        !          2031:     file after it changes. Example 10-13<a name="77050"></a>
        !          2032:     <i>Initialization</i></p>
        !          2033: <pre>
        !          2034:  var rdfFileURL = 'chrome://jarfly/content/jar.rdf';
1.1       david    2035:  var gTreeBody = null;
                   2036:  var gListbox = null;
                   2037:  var gRDF = null;
                   2038:  function onload( )
                   2039:  {
                   2040:    fileUtils = new FileUtils( );
                   2041:    path = fileUtils.chrome_to_path(rdfFileURL);
                   2042:    if(navigator.platform == "Win32") {
                   2043:      path = path.replace(/\//g,"\\");
                   2044:      // Only needed on Windows, until JSLib is fixed
                   2045:    }
1.9     ! petejc   2046:    gRDF = new RDFFile(path,'jar:flies','<a href=
        !          2047: "http://mozdev.org/fly-rdf">http://mozdev.org/fly-rdf</a>#');
        !          2048: </pre>
        !          2049:     <p>In <a href="#77050">Example 10-13</a>, the file URL is set
        !          2050:     to an RDF file in the chrome area. Note that both a
        !          2051:     <tt>&lt;tree&gt;</tt> and a <tt>&lt;listbox&gt;</tt>, which
        !          2052:     display the same data in different ways, will be updated with
        !          2053:     the same datasource. The <tt>onload</tt> function is called
        !          2054:     after the main XUL document is loaded. A class called
        !          2055:     <tt>FileUtils</tt> is initialized, which will create a path to
        !          2056:     the RDF file. If the file doesn't already exist, JSLib
        !          2057:     automatically creates it.</p>
        !          2058:     <p>Finally, the <tt>RDFFile</tt> is created by using the path
        !          2059:     and a root resource identifier, and the "xFly" namespace is
        !          2060:     used for the data references. <a href="#77052">Example
        !          2061:     10-14</a> shows that the RDF file is ready to have its data
        !          2062:     added and deleted. Example 10-14<a name="77052"></a> <i>Data
        !          2063:     updating</i></p>
        !          2064: <pre>
        !          2065:  function update( )
1.1       david    2066:  {
                   2067:    ...
                   2068:    var seqLength = 0;
                   2069:    if(gRDF.doesSeqExist('types'))
                   2070:    {
                   2071:      seqLength = gRDF.getSeqSubNodes('types').length;
                   2072:      //if(del)gRDF.removeSeq('types',false);
                   2073:    }
                   2074:    else
                   2075:      gRDF.addSeq('types');
                   2076:    for(i=0;i&lt;seqLength;i++)
                   2077:    {
                   2078:      tempItem = 'types:_' + (i+1);
                   2079:      if(gRDF.getAttribute(tempItem,'name')==name)
                   2080:        seqNumber = gRDF.getAttribute(tempItem,'number');
                   2081:    }
                   2082:    if(seqNumber == -1)
                   2083:    {
                   2084:      item = 'types:_' + (seqLength+1);
                   2085:      gRDF.setAttribute(item,'name',name);
                   2086:      gRDF.setAttribute(item,'number',seqLength+1);
                   2087:    }
                   2088:    else
                   2089:    {
                   2090:      item = 'types:_' + seqNumber;
                   2091:      gRDF.setAttribute(item,'number',seqNumber);
                   2092:    }
                   2093:    if(color!='')
                   2094:      gRDF.setAttribute(item,'color',color);
                   2095:    if(quantity!='')
                   2096:    {
                   2097:      gRDF.setAttribute(item,'quantity',quantity);
                   2098:      gRDF.setAttribute(item,'dead',calcDead(quantity,replace));
                   2099:    }
                   2100:    if(!del)
                   2101:      gRDF.addNode(item);
                   2102:    else
                   2103:      gRDF.removeNode(item);
                   2104:    gRDF.flush( );
1.9     ! petejc   2105:    onload( );
        !          2106: </pre>
        !          2107:     <p><a href="#77052">Example 10-14</a> contains a modified
        !          2108:     version of the <tt>update</tt> function. First, the function
        !          2109:     checks to see if a sequence called <tt>types</tt> is in the RDF
        !          2110:     file. If not, it creates one. Next, it appends an item to the
        !          2111:     sequence using <tt>type:_+(seqLength+1)</tt>. The same type of
        !          2112:     container setup was described in the section <a href=
        !          2113:     "#77104">"nsIRDFContainer</a>," earlier in this chapter.</p>
        !          2114:     <p>The <tt>update</tt> function then adds the color, quantity,
        !          2115:     and "dead" properties of that new item in the sequence. Next,
        !          2116:     it ensures that you actually want to add the item to the RDF
        !          2117:     file and flushes it out if not. It then recalls the
        !          2118:     <tt>onload</tt> function to update the template display.</p>
        !          2119:     <p>These are the basics of using <tt>RDFFile</tt>. As you can
        !          2120:     see, using JSLib for RDF is often much easier than trying to
        !          2121:     implement a similar setup on your own. More information about
        !          2122:     <tt>RDFFile</tt> and the other JSLib libraries can 
        !          2123:     <!--INDEX web sites:JSLib --> be 
        !          2124:     <!--INDEX ENDRANGE==RDF (Resource Description Framework):files:JSLib -->
        !          2125:     <!--INDEX ENDRANGE==JSLib libraries:RDF files --> 
        !          2126:     <!--INDEX ENDRANGE==files:RDF:JSLib --> found at <i><a href=
        !          2127:     "http://jslib.mozdev.org/">http://jslib.mozdev.org/</a></i>.</p>
        !          2128:     <h2><a name="77113"></a> Manifests</h2>
        !          2129:     <p>The package 
        !          2130:     <!--INDEX RDF (Resource Description Framework):manifest files -->
        !          2131:     <!--INDEX manifests:RDF --> descriptions, generally called
        !          2132:     <i>manifests</i>, use RDF to describe new packages and files to
        !          2133:     Mozilla. They can be added seamlessly because RDF provides a
        !          2134:     platform-like environment that facilitates the installation and
        !          2135:     use of new Mozilla software.</p>
        !          2136:     <p>All packages, including the ones that come preinstalled with
        !          2137:     Mozilla (such as the browser, the MailNews component, and the
        !          2138:     en-US language pack), have manifests describing them in terms
        !          2139:     of their relation to other packages. The manifests are
        !          2140:     typically files called <i>contents.rdf</i>, but they may also
        !          2141:     be called <i>manifest.rdf</i>. <a href="#77054">Example
        !          2142:     10-15</a> presents a <i>contents.rdf</i> file that describes a
        !          2143:     new skin for Mozilla. Example 10-15<a name="77054"></a> <i>Skin
        !          2144:     manifest</i></p>
        !          2145: <pre>
        !          2146:  &lt;?xml version="1.0"?&gt;
        !          2147:  &lt;RDF:RDF xmlns:RDF="&lt;/td&gt;<i><a href=
        !          2148: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#</i>"
        !          2149:    xmlns:chrome="&lt;/td&gt;<i><a href=
        !          2150: "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#</i>"&gt;
1.1       david    2151:  &lt;!-- List all the skins being supplied by this theme --&gt;
                   2152:  &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
                   2153:    &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;
                   2154:  &lt;/RDF:Seq&gt;
                   2155:  &lt;!-- Modern Information --&gt;
                   2156:  &lt;RDF:Description about="urn:mozilla:skin:modern/1.0"
                   2157:    chrome:displayName="Modern"
1.9     ! petejc   2158:    chrome:author="&lt;/td&gt;<i><a href=
        !          2159: "MAILTO:themes@mozilla.org">themes@mozilla.org</a></i>"
        !          2160:    chrome:name="&lt;/td&gt;<i><a href=
        !          2161: "MAILTO:themes@mozilla.org/modern/1.0">themes@mozilla.org/modern/1.0</a></i>"&gt;
1.1       david    2162:  &lt;chrome:packages&gt;
                   2163:    &lt;RDF:Seq about="urn:mozilla:skin:modern/1.0:packages"&gt;
                   2164:      &lt;--RDF:li resource="urn:mozilla:skin:modern/1.0:aim"/ --&gt;
                   2165:      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:communicator"/&gt;
                   2166:      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:editor"/&gt;
                   2167:      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:global"/&gt;
                   2168:      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:messenger"/&gt;
                   2169:      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0:navigator"/&gt;
                   2170:    &lt;/RDF:Seq&gt;
                   2171:  &lt;/chrome:packages&gt;
                   2172:  &lt;/RDF:Description&gt;
1.9     ! petejc   2173:  &lt;/RDF:RDF&gt;
        !          2174: </pre>
        !          2175:     <p>As you can see, the manifest is divided up into sections.
        !          2176:     After the preamble, where the XML processing instruction and
        !          2177:     the namespace declarations are made, an RDF sequence lists all
        !          2178:     the themes defined or supplemented (since you can create a
        !          2179:     package updated for only one Mozilla component, such as the
        !          2180:     browser) by this package. This section contains only one
        !          2181:     <tt>RDF:li-</tt>the modern theme.</p>
        !          2182:     <p>The next section gives more information on the theme, such
        !          2183:     as the author, the theme name, and a description. The
        !          2184:     <tt>chrome:packages</tt> structure that completes the manifest
        !          2185:     describes the packages to which this theme should be applied.
        !          2186:     All major components of the Netscape browser are listed in this
        !          2187:     example-including the AIM client that is not a part of
        !          2188:     Mozilla-but is skinned by themes such as Modern.</p>
        !          2189:     <h3><a name="77114"></a> RDF and Dynamic Overlays</h3>
        !          2190:     <p>Manifests can <!--INDEX dynamic overlays:RDF --> 
        !          2191:     <!--INDEX overlays:RDF --> 
        !          2192:     <!--INDEX RDF (Resource Description Framework):manifest files:dynamic overalys and -->
        !          2193:     <!--INDEX manifests:RDF:dynamic overlays and --> also add new
        !          2194:     menu items to existing Mozilla menus. When you add a new
        !          2195:     package to Mozilla, you should make it accessible from within
        !          2196:     the browser application, where users can access it easily. This
        !          2197:     is where RDF and dynamic overlays come in.</p>
        !          2198:     <p>The RDF you provide in your package makes it possible for
        !          2199:     the chrome registry, discussed in <a href=
        !          2200:     "ch06.html#77063">Chapter 6</a>, to find, understand, and
        !          2201:     register your new files. Packages must be registered if they
        !          2202:     are to be skinned, localized, or accessed using the special
        !          2203:     tools Mozilla provides (e.g., the chrome URL or XPConnect to
        !          2204:     the XPCOM libraries). If you do not register your package by
        !          2205:     providing the necessary RDF manifests, it cannot be accessed
        !          2206:     except as a disparate collection of files in the browser's main
        !          2207:     content window, which is not what you want.</p>
        !          2208:     <p>You can add overlays in Mozilla in two ways: import them
        !          2209:     explicitly by using an overlay processing instruction at the
        !          2210:     top of the XUL file into which items in the overlay file are to
        !          2211:     be "composed," or use RDF to register and load overlay files at
        !          2212:     runtime. This latter method will be used here to add an "xFly"
        !          2213:     item to the Tools menu of the Mozilla suite of
        !          2214:     applications.</p>
        !          2215:     <p><a href="#77056">Example 10-16</a> shows the
        !          2216:     <i>contents.rdf</i> manifest format that alerts Mozilla of the
        !          2217:     presence of an overlay, its target in the Mozilla application,
        !          2218:     and the package of which it is a part. Example 10-16<a name=
        !          2219:     "77056"></a> <i>Overlay for a sample application menu</i></p>
        !          2220: <pre>
        !          2221:  &lt;?xml version="1.0"?&gt;
        !          2222:  &lt;RDF:RDF xmlns:RDF="<a href=
        !          2223: "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
        !          2224:           xmlns:chrome="<a href=
        !          2225: "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
1.1       david    2226:    &lt;RDF:Seq about="urn:mozilla:package:root"&gt;
                   2227:      &lt;RDF:li resource="urn:mozilla:package:help"/&gt;
                   2228:    &lt;/RDF:Seq&gt;
                   2229:    &lt;RDF:Description about="urn:mozilla:package:help"
                   2230:          chrome:displayName="xFly Application"
                   2231:          chrome:author="xfly.mozdev.org"
                   2232:          chrome:name="xfly"&gt;
                   2233:    &lt;/RDF:Description&gt;
                   2234:    &lt;!-- Declare overlay points used in this package --&gt;
                   2235:    &lt;RDF:Seq about="urn:mozilla:overlays"&gt;
                   2236:      &lt;RDF:li resource="chrome://communicator/content/tasksOverlay.xul" /&gt;
                   2237:    &lt;/RDF:Seq&gt;
1.9     ! petejc   2238:    &lt;/td&gt;&lt;RDF:Seq about="chrome://communicator/content/tasksOverlay.xul"&gt;
1.1       david    2239:      &lt;RDF:li&gt;chrome://xfly/content/xflyOverlay.xul&lt;/RDF:li&gt;
                   2240:    &lt;/RDF:Seq&gt;
1.9     ! petejc   2241:  &lt;/RDF:RDF&gt;
        !          2242: </pre>
        !          2243:     <p>The manifest in <a href="#77056">Example 10-16</a> names the
        !          2244:     file <i>xflyOverlay.xul</i> as an overlay. Then it names
        !          2245:     <i>tasksOverlay.xul</i> as the base file into which the
        !          2246:     contents are placed. In this case, the overlays can overlay
        !          2247:     other overlay files arbitrarily. An overlay can define new
        !          2248:     content anywhere in the application. Overlays are often
        !          2249:     responsible for putting new items in menus. As long as the
        !          2250:     target and overlay <tt>id</tt>s match, any two RDF datasources
        !          2251:     are merged. You can try this example by putting a single new
        !          2252:     menu item in an overlay structure like the one shown in <a
        !          2253:     href="#77058">Example 10-17</a>. Save it as
        !          2254:     <i>xflyOverlay.xul</i> in the <i>xfly</i> content subdirectory
        !          2255:     and use the manifest information in <a href="#77056">Example
        !          2256:     10-16</a> as part of the packaging process described in <a
        !          2257:     href="ch06.html#77063">Chapter 6</a>. Example 10-17<a name=
        !          2258:     "77058"></a> <i>Overlay for an xFly menu item in the
        !          2259:     browser</i></p>
        !          2260: <pre>
        !          2261:  &lt;?xml version="1.0"?&gt;
1.1       david    2262:  &lt;overlay id="xflyMenuID"
1.9     ! petejc   2263:          xmlns:html="<a href=
        !          2264: "http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"
        !          2265:          xmlns="<a href=
        !          2266: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>"&gt;
1.1       david    2267:    &lt;menupopup id="tools_menu"&gt;
                   2268:      &lt;menuitem label="xfly xml editor"
                   2269:          oncommand="toOpenWindowByType('mozilla:xfly, 'chrome://xfly/content/');" /&gt;
                   2270:  &lt;/menupopup&gt;
1.9     ! petejc   2271:  &lt;/overlay&gt;
        !          2272: </pre>
        !          2273:     <p>The <tt>menupopup</tt> in Mozilla with the ID "tools_menu"
        !          2274:     gets a new menu item when this overlay is processed and its
        !          2275:     content included.</p>
        !          2276:     <hr>
        !          2277:     <hr>
        !          2278:     <a name="291"></a><a href="#b291">[Back]</a> <a name=
        !          2279:     "77060"></a> A vector, for those who don't know, is a flexible
        !          2280:     and more accessible version of the array data structure. 
        !          2281:     <hr>
        !          2282:     <br>
        !          2283:     <br>
        !          2284:     File a <a href=
        !          2285:     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
        !          2286:     for chapter 10. <!-- ?php require(NOTES); ? -->
        !          2287:     <?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch10'; require(NOTES); ?>

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