[Project_owners] Problems with nsIRDFDataSource.AppendElement()

Neil Deakin enndeakin at sympatico.ca
Fri Jun 10 15:35:26 EDT 2005


Alex Eng wrote:

>> Alex Eng wrote:
>>
>>>> In my code, I'm adding a new RDF node to an <RDF:Seq> using the 
>>>> AppendElement() method of the nsIRDFDataSource interface, as per 
>>>> the following code excerpt:
>>>>
>>>>   var rdfSvc = 
>>>> Components.classes["@..."].getService(Components.interfaces.nsIRDFService); 
>>>>
>>>>   var rdfContainer = 
>>>> Components.classes["@..."].createInstance(Components.interfaces.nsIRDFContainer); 
>>>>
>>>>   var dataSource;
>>>>
>>>>   // Get data source, call rdfContainer.Init(), etc....
>>>>
>>>>   var newNode = rdfSvc.GetAnonymousResource();
>>>>   var prop = rdfSvc.GetResource("http://...#name");
>>>>   var target = rdfSvc.GetLiteral("Joel User");
>>>>
>>>>   try {
>>>>     dataSource.Assert(newNode, prop, target, true);
>>>>     rdfContainer.AppendElement(newNode);
>>>>   } catch (e) {
>>>>     alert(e);
>>>>   }
>>>>   // ...
>>>>
>>>>
>>>> It appears that the line
>>>>
>>>>    rdfContainer.AppendElement(newNode);
>>>>
>>>> seems to do nothing - i.e., no new node is added to the <RDF:Seq> 
>>>> container.  Substituting the call to AppendElement() with 
>>>> InsertElementAt(), i.e.,
>>>>
>>>>    rdfContainer.InsertElementAt(newNode, 1, true);
>>>>
>>>> won't work, as InsertElementAt() will return NS_ERROR_FAILURE.
>>>>
>>>> Is there something that I'm doing wrong here?  How can I get 
>>>> AppendElement() to do what it's supposed to do?  Thanks.
>>>
>>
>>
>>
>> This is all smelling like you're not actually having a container in 
>> the datasource. Note that if you want to start a container from 
>> scratch, your approach won't do it, containerutils is going to fix 
>> that for you. If you have an existing Seq, you're making a mistake 
>> outside the code that you quoted.
>>
>> Axel
>
>
> Axel,
>
> Here's the initialization code that was omitted:
>
> ---------------------------------------------------------------------
> // Global declarations
> //...
> var rdfContainerUtils = 
> Components.classes["@..."].createInstance(Components.interfaces.nsIRDFContainerUtils); 
>
>
> function init()
> {
>   var lbClippings = document.getElementById("lbClippings");
>   var dataSrcs = lbClippings.database.GetDataSources();
>   var rootNode = 
> rdfSvc.GetResource("http://clippings.mozdev.org/rdf/user-clippings
> ");
>
>   while (dataSrcs.hasMoreElements()) {
>     dataSource = dataSrcs.getNext();
>     try {
>       dataSource = 
> dataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
>       rdfContainer.Init(dataSource, rootNode);
>     }
>     catch (e) {
>       // Root node doesn't exist, probably because this is first-time run
>       rdfContainerUtils.MakeSeq(dataSource, rootNode);
>       rdfContainer.Init(dataSource, rootNode);
>     }
>   }
> }
> ----------------------------------------------------------------------
>
> Note that if the <RDF:Seq> node doesn't exist, MakeSeq() is called, 
> and then rdfContainer.Init() is invoked again.
>
You can just call MakeSeq and not call Init, it will just return the 
existing a container if it is already there.

/ Neil



More information about the Project_owners mailing list