A biblioteca n3.js é uma implementação da especificação de baixo nível rdf.js que permite lidar com o RDF em JavaScript facilmente. Oferece:
Analisar e escrever é:
Para Node.js, o n3.js vem como um pacote NPM.
$ npm install n3
const N3 = require ( 'n3' ) ;
O n3.js funciona perfeitamente em navegadores via webpack ou navegador. Se você não estiver familiarizado com essas ferramentas, pode ler o WebPack: Criando um pacote - Introdução ou Introdução ao Browserify . Você precisará criar um "pacote UMD" e fornecer um nome (por exemplo, com a opção -s N3
no navegador).
Você também pode carregá -lo via CDN:
< script src =" https://unpkg.com/n3/browser/n3.min.js " > </ script >
N3.JS segue a especificação de baixo nível RDF.JS.
N3.DataFactory
fornecerá as funções de fábrica para criar triplos e quads:
const { DataFactory } = N3 ;
const { namedNode , literal , defaultGraph , quad } = DataFactory ;
const myQuad = quad (
namedNode ( 'https://ruben.verborgh.org/profile/#me' ) , // Subject
namedNode ( 'http://xmlns.com/foaf/0.1/givenName' ) , // Predicate
literal ( 'Ruben' , 'en' ) , // Object
defaultGraph ( ) , // Graph
) ;
console . log ( myQuad . termType ) ; // Quad
console . log ( myQuad . value ) ; // ''
console . log ( myQuad . subject . value ) ; // https://ruben.verborgh.org/profile/#me
console . log ( myQuad . object . value ) ; // Ruben
console . log ( myQuad . object . datatype . value ) ; // http://www.w3.org/1999/02/22-rdf-syntax-ns#langString
console . log ( myQuad . object . language ) ; // en
No restante deste documento, trataremos “Triplos” e “Quads” igualmente: assumimos que um quad é simplesmente um triplo em um gráfico nomeado ou padrão.
N3.Parser
transforma o documento Turtle, Trig, N-TriPles ou N-Quads em quadríceps por meio de um retorno de chamada:
const tomAndJerry = `PREFIX c: <http://example.org/cartoons#>
# Tom is a cat
c:Tom a c:Cat.
c:Jerry a c:Mouse;
c:smarterThan c:Tom.`
const parser = new N3 . Parser ( ) ;
parser . parse ( tomAndJerry ,
( error , quad , prefixes ) => {
if ( quad )
console . log ( quad ) ;
else
console . log ( "# That's all, folks!" , prefixes ) ;
} ) ;
O primeiro argumento do retorno de chamada é um valor de erro opcional, o segundo é um quad. Se não houver mais quads, o retorno de chamada será invocado uma última vez com null
para quad
e um hash de prefixos como terceiro argumento.
Como alternativa, um objeto pode ser fornecido, onde onQuad
, onPrefix
e onComment
são usados para ouvir quads
, prefixes
e comments
da seguinte forma:
const parser = new N3 . Parser ( ) ;
parser . parse ( tomAndJerry , {
// onQuad (required) accepts a listener of type (quad: RDF.Quad) => void
onQuad : ( err , quad ) => { console . log ( quad ) ; } ,
// onPrefix (optional) accepts a listener of type (prefix: string, iri: NamedNode) => void
onPrefix : ( prefix , iri ) => { console . log ( prefix , 'expands to' , iri . value ) ; } ,
// onComment (optional) accepts a listener of type (comment: string) => void
onComment : ( comment ) => { console . log ( '#' , comment ) ; } ,
} ) ;
Se não forem fornecidos retornos de chamada, a análise acontecerá de maneira síncrona, devolvendo uma variedade de quadríceps:
const parser = new N3 . Parser ( ) ;
// An array of resultant Quads
const quadArray = parser . parse ( tomAndJerry ) ;
Por padrão, N3.Parser
analisa um superconjunto permissivo de tartaruga, trigo, n-triples e n-quadros.
Para compatibilidade estrita com qualquer um desses idiomas, passe um argumento format
sobre a criação:
const parser1 = new N3 . Parser ( { format : 'N-Triples' } ) ;
const parser2 = new N3 . Parser ( { format : 'application/trig' } ) ;
A notação3 (N3) é suportada apenas através do argumento format
:
const parser3 = new N3 . Parser ( { format : 'N3' } ) ;
const parser4 = new N3 . Parser ( { format : 'Notation3' } ) ;
const parser5 = new N3 . Parser ( { format : 'text/n3' } ) ;
É possível fornecer o IRI base do documento que você deseja analisar. Isso é feito passando por um argumento baseIRI
sobre a criação:
const parser = new N3 . Parser ( { baseIRI : 'http://example.org/' } ) ;
Por padrão, N3.Parser
prefixará rótulos de nó em branco com um prefixo b{digit}_
. Isso é feito para evitar colisões de nós em branco não relacionados, com rótulos idênticos. O argumento do construtor blankNodePrefix
pode ser usado para modificar o prefixo ou, se definido como uma string vazia, desativar completamente o prefixação:
const parser = new N3 . Parser ( { blankNodePrefix : '' } ) ;
N3.Parser
pode analisar os fluxos Node.js à medida que crescem, retornando quads assim que estiverem prontos.
const parser = new N3 . Parser ( ) ,
rdfStream = fs . createReadStream ( 'cartoons.ttl' ) ;
parser . parse ( rdfStream , console . log ) ;
N3.StreamParser
é um fluxo Node.js e RDF.js Sink Implementation. Esta solução é ideal se o consumidor for mais lento, pois os dados de origem são lidos apenas quando o consumidor estiver pronto.
const streamParser = new N3 . StreamParser ( ) ,
rdfStream = fs . createReadStream ( 'cartoons.ttl' ) ;
rdfStream . pipe ( streamParser ) ;
streamParser . pipe ( new SlowConsumer ( ) ) ;
function SlowConsumer ( ) {
const writer = new require ( 'stream' ) . Writable ( { objectMode : true } ) ;
writer . _write = ( quad , encoding , done ) => {
console . log ( quad ) ;
setTimeout ( done , 1000 ) ;
} ;
return writer ;
}
Um evento prefix
dedicado sinaliza todos os prefixos com prefix
e argumentos term
. Um evento comment
dedicado pode ser ativado definindo comments: true
no construtor n3.streamparser.
N3.Writer
serializa os quads como um documento RDF. Escreva quadríceps através addQuad
.
const writer = new N3 . Writer ( { prefixes : { c : 'http://example.org/cartoons#' } } ) ; // Create a writer which uses `c` as a prefix for the namespace `http://example.org/cartoons#`
writer . addQuad ( quad (
namedNode ( 'http://example.org/cartoons#Tom' ) , // Subject
namedNode ( 'http://example.org/cartoons#name' ) , // Predicate
literal ( 'Tom' ) // Object
) ) ;
writer . end ( ( error , result ) => console . log ( result ) ) ;
Por padrão, N3.Writer
escreve Turtle (ou TRIG se alguns quads estiverem em um gráfico nomeado).
Para escrever N-TriPles (ou N-QADs), passe um argumento format
sobre a criação:
const writer1 = new N3 . Writer ( { format : 'N-Triples' } ) ;
const writer2 = new N3 . Writer ( { format : 'application/trig' } ) ;
N3.Writer
também pode escrever quadríceps em um fluxo node.js através addQuad
.
const writer = new N3 . Writer ( process . stdout , { end : false , prefixes : { c : 'http://example.org/cartoons#' } } ) ;
writer . addQuad (
namedNode ( 'http://example.org/cartoons#Tom' ) , // Subject
namedNode ( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' ) , // Predicate
namedNode ( 'http://example.org/cartoons#Cat' ) // Object
) ;
writer . addQuad ( quad (
namedNode ( 'http://example.org/cartoons#Tom' ) , // Subject
namedNode ( 'http://example.org/cartoons#name' ) , // Predicate
literal ( 'Tom' ) // Object
) ) ;
writer . end ( ) ;
N3.StreamWriter
é um fluxo Node.js e RDF.js Sink implementação.
const streamParser = new N3 . StreamParser ( ) ,
inputStream = fs . createReadStream ( 'cartoons.ttl' ) ,
streamWriter = new N3 . StreamWriter ( { prefixes : { c : 'http://example.org/cartoons#' } } ) ;
inputStream . pipe ( streamParser ) ;
streamParser . pipe ( streamWriter ) ;
streamWriter . pipe ( process . stdout ) ;
Você pode querer usar as anotações […]
e listar (…)
de tartaruga e trigo. No entanto, um escritor de streaming não pode criá -los automaticamente: as notações abreviadas só são possíveis se os nós em branco ou as cabeças da lista não forem usados posteriormente, o que só pode ser determinado conclusivamente no final do fluxo.
As funções blank
e list
permitem criá -las manualmente:
const writer = new N3 . Writer ( { prefixes : { c : 'http://example.org/cartoons#' ,
foaf : 'http://xmlns.com/foaf/0.1/' } } ) ;
writer . addQuad (
writer . blank (
namedNode ( 'http://xmlns.com/foaf/0.1/givenName' ) ,
literal ( 'Tom' , 'en' ) ) ,
namedNode ( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' ) ,
namedNode ( 'http://example.org/cartoons#Cat' )
) ;
writer . addQuad ( quad (
namedNode ( 'http://example.org/cartoons#Jerry' ) ,
namedNode ( 'http://xmlns.com/foaf/0.1/knows' ) ,
writer . blank ( [ {
predicate : namedNode ( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' ) ,
object : namedNode ( 'http://example.org/cartoons#Cat' ) ,
} , {
predicate : namedNode ( 'http://xmlns.com/foaf/0.1/givenName' ) ,
object : literal ( 'Tom' , 'en' ) ,
} ] )
) ) ;
writer . addQuad (
namedNode ( 'http://example.org/cartoons#Mammy' ) ,
namedNode ( 'http://example.org/cartoons#hasPets' ) ,
writer . list ( [
namedNode ( 'http://example.org/cartoons#Tom' ) ,
namedNode ( 'http://example.org/cartoons#Jerry' ) ,
] )
) ;
writer . end ( ( error , result ) => console . log ( result ) ) ;
N3.Store
permite armazenar triplos na memória e encontrá -los rapidamente.
Neste exemplo, criamos uma nova loja e adicionamos os triplos :Pluto a :Dog.
e :Mickey a :Mouse
.
Em seguida, encontramos triplos com :Mickey
como sujeito.
const store = new N3 . Store ( ) ;
store . add (
quad (
namedNode ( 'http://ex.org/Pluto' ) ,
namedNode ( 'http://ex.org/type' ) ,
namedNode ( 'http://ex.org/Dog' )
)
) ;
store . add (
quad (
namedNode ( 'http://ex.org/Mickey' ) ,
namedNode ( 'http://ex.org/type' ) ,
namedNode ( 'http://ex.org/Mouse' )
)
) ;
// Retrieve all quads
for ( const quad of store )
console . log ( quad ) ;
// Retrieve Mickey's quads
for ( const quad of store . match ( namedNode ( 'http://ex.org/Mickey' ) , null , null ) )
console . log ( quad ) ;
Se você estiver usando várias lojas, poderá reduzir o consumo de memória, permitindo que eles compartilhem um índice de entidade:
const entityIndex = new N3 . EntityIndex ( ) ;
const store1 = new N3 . Store ( [ ] , { entityIndex } ) ;
const store2 = new N3 . Store ( [ ] , { entityIndex } ) ;
Dataset
Esta loja adere à interface Dataset
que expõe as seguintes propriedades
Atributos:
size
-um número inteiro não negativo que especifica o número de quads no conjunto.Métodos:
add
- Adiciona o Quad especificado ao conjunto de dados. Os quadríceps existentes, conforme definido em Quad.equals
, serão ignorados.delete
- Remove o Quad especificado do conjunto de dados.has
- determina se um conjunto de dados inclui um determinado quad.match
- Retorna um novo conjunto de dados composto por todos os quadríceps na instância atual que corresponde aos argumentos fornecidos.[Symbol.iterator]
- implementa o protocolo do iterador para permitir a iteração em todos quads
no conjunto de dados, como no exemplo acima. A loja implementa os seguintes métodos de manipulação, além da interface padrão Dataset
(documentação):
addQuad
para inserir um quadaddQuads
para inserir uma variedade de quadrícegosremoveQuad
para remover um quadremoveQuads
para remover uma variedade de quadrícegosremove
para remover um fluxo de quadsremoveMatches
para remover todos os quads correspondentes ao padrão fornecidodeleteGraph
para remover todos os quadriláteros com o gráfico fornecidocreateBlankNode
retorna um identificador de nó em branco não utilizadoA loja fornece os seguintes métodos de pesquisa (documentação):
match
retorna um fluxo e gerador de quads correspondentes ao padrão fornecidogetQuads
retorna uma variedade de quads correspondentes ao padrão fornecidocountQuads
conta o número de quads correspondentes ao padrão fornecidoforEach
executa um retorno de chamada em todos os quads correspondentesevery
retorna se um retorno de chamada nos quads correspondentes sempre retorna verdadeirosome
retornam se um retorno de chamada para os quads correspondentes retorna true pelo menos uma vezgetSubjects
Retorna uma variedade de assuntos únicos que ocorrem em quadriláteros correspondentesforSubjects
executa um retorno de chamada em assuntos únicos que ocorrem em quadras correspondentesgetPredicates
retorna uma variedade de predicados únicos que ocorrem na correspondência QuadforPredicates
executam um retorno de chamada em predicados únicos que ocorrem em quadrs correspondentesgetObjects
retorna uma variedade de objetos únicos que ocorrem na correspondência QuadforObjects
executa um retorno de chamada em objetos únicos que ocorrem em quadrícegos correspondentesgetGraphs
retorna uma variedade de gráficos únicos que ocorrem na Quad correspondenteforGraphs
executa um retorno de chamada em gráficos exclusivos que ocorrem em quadrícegos correspondentes O n3.js suporta o raciocínio da seguinte maneira:
import { Reasoner , Store , Parser } from 'n3' ;
const parser = new Parser ( { format : 'text/n3' } ) ;
const rules = `
{
?s a ?o .
?o <http://www.w3.org/2000/01/rdf-schema#subClassOf> ?o2 .
} => {
?s a ?o2 .
} .
`
const rulesDataset = new Store ( parser . parse ( rules ) ) ;
const dataset = new Store ( /* Dataset */ )
// Applies the rules to the store; mutating it
const reasoner = new Reasoner ( store ) ;
reasoner . reason ( rules ) ;
NOTA : N3.JS atualmente suporta apenas regras com padrões de gráficos básicos na premissa e conclusão. Build-ins e encadeamento para trás não são suportados. Para um RDF/JS Razoer que suporta todos os recursos de raciocínio de notação3, consulte Eye-JS.
O analisador e o escritor n3.js é totalmente compatível com as seguintes especificações do W3C:
Além disso, o N3.JS Parser também suporta notação3 (N3) (ainda não há especificação oficial).
O analisador e o escritor n3.js também são totalmente compatíveis com as variantes RDF-Star das especificações do W3C.
O modo padrão é permissivo e permite uma mistura de diferentes sintaxes, incluindo RDF-Star. Passe uma opção format
para o construtor com o nome ou o tipo MIME de um formato para um comportamento rigoroso e intolerante a falhas. Se uma sequência de formato contiver star
ou *
(por exemplo, turtlestar
ou TriG*
), o suporte a estrela rdf para esse formato será ativado.
Os submódulos n3.js são compatíveis com as seguintes interfaces rdf.js:
N3.DataFactory
implementos DataFactory
Term
de implementação e um de NamedNode
, BlankNode
, Literal
, Variable
, DefaultGraph
Term
de implementação, Triple
e Quad
N3.StreamParser
implementa Stream
e Sink
N3.StreamWriter
implementa Stream
e Sink
N3.Store
Store implementa Source
Store
de dados Sink
DatasetCore
A biblioteca n3.js é protegida por direitos autorais de Ruben Verborgh e liberada sob a licença do MIT.
As contribuições são bem -vindas, e relatórios de bugs ou solicitações de tração são sempre úteis. Se você planeja implementar um recurso maior, é melhor entrar em contato comigo primeiro.