L'interfaccia nsIRDFDataSource fornisce alcuni metodi per fare ricerche in una datasource RDF. Le due datasource comuni in-memory-datasource e xml-datasource implementano tutti questi metodi. Comunque, altre datasource potrebbero non implementare tutte le funzioni. Se un metodo non è implementato in una datasource, verrà lanciata un'eccezione quando il metodo viene chiamato. Questo è vero per molte delle datasource incorporate in Mozilla, cioà quelle che iniziano con 'rdf:' che sono fornite con Mozilla. Questi metodi non sono implementati dal momento che non sono necessari per qil prodotto.
Poiché RDF memorizza triple di dati, puoi ricercare i dati
fornendo una parte della tripla. Per esempio, se ha il soggetto e il
predicato della tripla, puoi ricercare nella datasource i complementi
presenti. In maniera analoga, se ha il predicato e il complemento, puoi
ottenere i soggetti.
Gli esempi in questa sezione usano l'RDF dell'esempio della famiglia di Karen da una sezione precedente. La rappresentazione RDF/XML di questi dati RDF è ripetuta di seguito.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:wordnet="http://xmlns.com/wordnet/1.6/"
xmlns:people="http://www.xulplanet.com/rdf/people/">
<wordnet:Person rdf:about="http://www.xulplanet.com/rdf/people/Karen" people:name="Karen">
<people:children>
<rdf:Seq rdf:about="http://www.xulplanet.com/rdf/people/KarensKids">
<rdf:li>
<wordnet:Person rdf:about="http://www.xulplanet.com/rdf/people/Sandra" people:name="Sandra"/>
</rdf:li>
<rdf:li>
<wordnet:Person rdf:about="http://www.xulplanet.com/rdf/people/Kevin" people:name="Kevin"/>
</rdf:li>
<rdf:li>
<wordnet:Person rdf:about="http://www.xulplanet.com/rdf/people/Jack" people:name="Jack"/>
</rdf:li>
</rdf:Seq>
</people:children>
</wordnet:Person>
</rdf:RDF>
Di seguito c'è un elenco dei metodi di ricerca disponibili in tutte le datasource RDF. La tabella mostra la funzione che devi chiamare quando hai alcune parti di una tripla e vuoi un'altra parte della tripla. Per esempio, la prima riga indica che se hai il soggetto della tripla, e vuoi ottenere i predicati che sono legati a quel soggetto, usa la funzione ArcLabelsOut.
| Hai | Vuoi | Metodo | ||
|---|---|---|---|---|
| Soggetto | Predicato | Complemento | ||
| X | Predicato | ArcLabelsOut | ||
| X | Complemento | ArcLabelsOut e poi GetTarget(s) | ||
| X | X | Complemento | GetTarget o GetTargets | |
| X | Predicato | ArcLabelsIn | ||
| X | Soggetto | ArcLabelsIn e poi GetSource(s) | ||
| X | X | Soggetto | GetSource or GetSources | |
| X | X | Esistenza del complemento |
hasArcOut | |
| X | X | Esistenza del soggetto |
hasArcIn | |
| X | X | X | Esistenza | HasAssertion |
Il metodo più comunemente usato è GetTarget. Questo metodo ritornerà un solo complemento, dato il soggeto e il predicato. Diciamo che vogliamo recuperare il nome della risorsa Karen. L'URI della risorsa Karen è http://www.xulplanet.com/rdf/people/Karen. Prima, otteniamo la risorsa usando il servizio RDF.
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
getService(Components.interfaces.nsIRDFService);
var karen = rdfService.GetResource("http://www.xulplanet.com/rdf/people/Karen");
Ricorda che le risorse sono oggetti globali. Se Karen appare in un'altra datasource, entrambe le risorse saranno lo stesso oggetto. Questo rende facile la fusione di due datasources.
Poi, usiamo il metodo GetTarget per recuperare il nome di Karen. Usiamo questo metodo perché abbiamo il soggetto (la risorsa Karen che abbiamo appena recuperato con il servizio RDF) e il predicato che è 'name'. Abbiamo bisono di qualificare il predicato con lo spazio di nomi. Nell'RDF/XML sopra, viene usato il prefisso dello spazio di nomi people, ma ovviamente non possiamo usare il prefisso nel codice, visto che solo un'abbreviazione XML. Avremo bisogno di usare l'URI completo che è http://www.xulplanet.com/rdf/people/name. Siccome il predicato è anche una risorsa, lo recuperiamo tramite il servizio RDF, come il soggetto.
var name = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var target = datasource.GetTarget(karen, name, true);
Al metodo GetTarget vengono passate le risorse soggetto e predicato. Ritorna il target come nodo RDF. Il metodo ritorna sempre oggetti che implementano l'interfaccia nsIRDFNode, mai direttamente le interfacce reource o litera. Se vuoi queste interfacce, avrai bisogno di cambiare l'interfaccia usando QueryInterface. Nel caso di Karen, assumeremo che il suo nome è un letterale e otterremo il valore del nome. Nota che il valore ritornato non è una stringa. Nessuna delle interfacce di ricerca RDF lavora direttamente sulle stringhe.
var karensname;
var target = datasource.GetTarget(karen, name, true);
if (target instanceof Components.interfaces.nsIRDFLiteral){
karensname = target.Value;
}
L'operatore instanceof controlla se il valore di 'target' è un letterale RDF, e in tal caso ha anche l'effetto collaterale di inviare il valore all'interfaccia. Questo uso è utie anche perché possiamo fare le operazioni contemporaneamente. Se il target è nullo, significa che non esisteva. In questo esempio il target sarà nullo se Karen non ha un name specificato. Nel blocco if, il valore del letterale è recuperato come stringa usando la proprietà Value.
Potresti aver notato che il metodo GetTarget ha un terzo argomento che è impostato a True sopra. Viene utilizzato per indicare se vuoi ritornare una tripla negativa invece di una normale. Questa è una funzione specifica di Mozilla, che permette a una dichiarazione RDF di essere falsa invace che vera. Ricorda che quando un pezzo di informazione non è fornita nella datasource, significa che la datasource non conosce quella informazione, oppure che c'è un informazione vuota. Per esempio, se non avessimo specificato il nome di Karen nell'RDF/XML, significherebbe che il nome di Karen non è conosciuto alla datasource. Comunque potrebbe in ogni caso avere un nome,
Una tripla negativa indica che una dichiarazione particolare non è vera. Per esempio, potremmo aggiungere una dichiarazione che il nome di Karen non è 'Tracy'. Nota che non c'è attualmente modo di specificare questo in RDF/XML, solo modificando direttamente la datasource. Comunque, generalmente le triple negative andrebbero evitate. Non ofrono molto e generalmente questo tipo di informazioni è meglio specificato in altri modi.
Comunque, se il terzo argomento per il metodo GetTarget è false, ritornerà solo triple negative. Comunque, per quasi tutti gli scopi, dovrebbe essere dato true per questo argomento.
Il metodo GetTarget ritornerà solo uno degli oggetti che esistono nella datasource. Se Karen avesse diversi nomi, solo uno di loro sarebbe ritornato. Il metodo relativo GetTargets ritornerà una lista di tutti i nomi. Non dovresti mai dare importanza all'ordine in cui sono riportati i nomi, visto che i dati RDF non sono in un ordine particolare. Anche se il metoro GetTarget ritornerà probabilmente lo stesso valore in ogni chiamata successiva, il valore può esere diverso ogni volta che la tua applicazione viene avviata.
Il metodo GetTargets ritornerà un elenco che è un oggetto che può essere usato per navigare tra i risultati in sequenza.
var targets = datasource.GetTargets(karen, name, true);
while (targets.hasMoreElements()){
var name = targets.getNext();
if (name instanceof Components.interfaces.nsIRDFLiteral){
alert(name.Value);
}
}
L'elenco implementa l'interfaccia nsISimpleEnumeration e ha due funzioni, hasMoreElements per vedere se tutti gli elementi sono stati visionati, e getNext
per ottenere il prossimo elemento nella sequenza. Il loop sopra
passerà ogni elemento esistente. Deve essere per forza fatta una
modifica ad ogni risultato. Se non esiste alcun risultato, verrà
ritornato un elenco vuoto, che significa che la chiamata hasMoreElements ritornerà smpre falso. Nota che il metodo GetTargets non ritorna mai null.
Ci sono anche due metodi GetSource e GetSources che lavorano nella direzione opposta. Questo significa che possiamo ottenere la risorsa Karen, dato il suo nome come letterale. Combinando i metodi di richiamo oggetto e sorgente, possiamo raggiungere qualunque punto del grafico RDF.
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
getService(Components.interfaces.nsIRDFService);
var karensname = rdfService.GetLiteral("Karen");
var name = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var subject= datasource.GetSource(name, karensname, true);
Questo codice troverà la risorsa Karen che è http://www.xulplanet.com/rdf/people/Karen.
Funziona in maniera simile ai metodi di ricerca del complemento, a
parte il fatto che va nella direzione opposta. Fornendo il nome di
Karen, possiamo determinare quali risorse hanno quel nome usando il
predicato 'name'. Il metodo GetSource prende il predicato, complemento e true/false come argomenti. Il predicato è il primo argomento a differenza del metodo GetTarget, dove è il secondo argomento. Il metodo GetSource ritorna sempre un oggetto nsIRDFResource visto che i letterali non possono avere proprietà, così puoi usare i metodi di nsIRDFResource direttamente, senza modificare il risultato.
C'è anche un metodo GetSources che ritornerà un elenco di tutte le sorgenti esistenti. Questo dovrebbe essere usato nel caso in cui diverse persone abbiano il nome Karen.
A volte vorrai determinare quali predicati sono specificati per un
dato nodo nella datasource. Per esempio, data solo la risorsa Karen,
potresti aver bisogno di trovare quali proprietà abbia.
Nell'esempio Karen ha tre proprietà, il suo nome, il suo tipo e
i suoi figli. Il nome ha il valore Karen, il tipo è http://xmlns.com/wordnet/1.6/Person. La proprietà 'children' è una risorsa
http://www.xulplanet.com/rdf/people/KarensKids. E' possibile che siano aggiunge anche altre proprietà in seguito.
Se vuoi determinare quali proprietà appartengono ad una risorsa, usa il metodo GetArcsOut della datasource. Ritorna un elenco di tutti i predicati che interessano una risorsa. Se questo metodo è chiamato sulla risorsa Karen, l'elenco conterrà tre valori.
var karen = rdfService.GetResource("http://www.xulplanet.com/rdf/people/Karen");
var targets = datasource.ArcLabelsOut(karen);
while (targets.hasMoreElements()){
var predicate = targets.getNext();
if (predicate instanceof Components.interfaces.nsIRDFResource){
alert(predicate.Value);
}
}
L'elenco ritorna tre risorse predicato, non il valore dei predicati. Perciò i valori ritornati sarebbero risorse con i valori http://www.xulplanet.com/rdf/people/name, http://www.xulplanet.com/rdf/people/children, e http://www.w3.org/1999/02/22-rdf-syntax-ns#type. Ricorda che RDF non è ordinato, così i risultati non saranno riportati in un ordine particolare. La numerazione ritorna sempre oggetti genericinsISupports, perciò dovrai analizzare i risultati che vengono dal metodo getNext. Nel caso degli elenchi creati dal metodo ArcLabelsOut, i valori saranno sempre nsIRDFResources, viso che i predicati sono sempre risorse.
Una volta ottenuta una risorsa predicato, puoi fornirla come argomento a GetTarget per ottenere il valore del predicato per quella risorsa. Per esempio il codice di seguito prenderà il valore dei predicati trovati.
var karen = rdfService.GetResource("http://www.xulplanet.com/rdf/people/Karen");
var targets = datasource.ArcLabelsOut(karen);
while (targets.hasMoreElements()){
var predicate = targets.getNext();
if (predicate instanceof Components.interfaces.nsIRDFResource){
var target = datasource.GetTarget(karen, predicate, true);
if (target instanceof Components.interfaces.nsIRDFResource){
alert("Resource is: " + target.Value);
}
else if (target instanceof Components.interfaces.nsIRDFLiteral){
alert("Literal is: " + target.Value);
}
}
}
In questo caso, abbiamo bisogno di controllare per entrambe le interfacce nsIRDFResource e nsIRDFLiteral,
mentre le altre due il tipo e i figli, sono risorse e non sappiamo
l'ordine in cui saranno ritornate. E' una buona idea fare questo
controllo in ogni caso finché non hai la certezza assoluta di
che tipo di nodo verrà ritornato.
Nota che se due predicati 'name' partono da una risorsa, per esempio, se Karen ha due nomi, nell'elenco verrà ritornato solo un predicato 'name'. Gli elenchi non conterranno mai duplicati. In questo caso avrai bisogno di usare il metodo GetTargets per ottenere i valori.
Il metodo ArcLabelsIn è simile a ArcLabelsOut, ma opera nella
direzione opposta. Per esempio, dato il letterale 'Karen', potremmo
determinare quali predicati sono usati per puntare al valore.
Nell'esempio, verrebbe ritornato solo un valore nell'elenco, il
predicato 'name'. Ma immagina che qualcuno abbia il nome 'April'.
Questo sarebbe utilizzato per indicare il nome di qualcuno, ma potrebbe
anche essere usato da qualche altra parte nella datasource per
specificcare il mese di qualcosa usando il predicato 'month'. In questa
situazione verranno ritornati entrambe i predicati, ache se non sono
parte della stessa risorsa. E' questa caratteristica che rende la
navigazione del grafico RDF piuttosto potente.
Tre metodi addizionali delle datasource ti permettono di controllare l'esistenza di dati nell'RDF. Il metodo hasArcOut può essere usato per controllare se da un nodo parte un qualche predicato. Quesot metodo è simile al metodo GetTarget eccetto che non ritorna il complemento, solo un booleano che indica se il predicato esiste o no. Questo metodo potrebbe essere pù efficace per alcune datasource. Per esempio, potremmo controllare se Karen ha o non ha un nome usando il seguente codice:
var karen = rdfService.GetResource("http://www.xulplanet.com/rdf/people/Karen");
var name = rdfService.GetResource("http://www.xulplanet.com/rdf/people/name");
var hasName = datasource.hasArcOut(karen, name);
Il risultato del metodo hasArcOut sarà true o false. In questo esempio, il risultato sarà true. C'è anche il relativo metodo hasArcIn per controllare l'esistenza di un predicato. Nota che questi due metodi iniziano con una lettera minuscola, al contrario degli altri metodi delle datasource.
Il metodo HasAssertion può essere usato per controllare una tripla nella datasource date le tre parti della tripla. Questo potrebbe permetterti di controllare se Karen ha un nome specifico. Questo metodo ritornerà true se la tripla esiste, e false se non esiste.
Infine, le datasource forniscono un metodo GetAllResources che ritornerà un elenco di tutte le risorse che sono usate come soggetti nella datasource. Nell'esempio, cinque valori saranno ritornati. Non c'è un metodo analogo per recuperare tutti i letterali. Per fare questo, avrai bisogno di iterare risorsa per risorsa usado GetAllResources, chiamare ArcLabelsOut su ogni risorsa e quindi GetTargets per ottenere ogni complemento. Solo così si potranno attraversare tutti i dati nella datasource.