La Biblioteca N3.JS es una implementación de la especificación de bajo nivel RDF.JS que le permite manejar fácilmente RDF en JavaScript. Ofrece:
Analizar y escribir es:
Para Node.js, N3.JS viene como un paquete NPM.
$ npm install n3
const N3 = require ( 'n3' ) ;
N3.JS funciona sin problemas en los navegadores a través de Webpack o Browserify. Si no está familiarizado con estas herramientas, puede leer Webpack: crear un paquete: comenzar o introducir para navegar . Deberá crear un "paquete UMD" y proporcionar un nombre (por ejemplo, con la opción -s N3
en Browserify).
También puede cargarlo a través de CDN:
< script src =" https://unpkg.com/n3/browser/n3.min.js " > </ script >
N3.JS sigue la especificación de bajo nivel RDF.JS.
N3.DataFactory
le dará las funciones de fábrica para crear triples y 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
En el resto de este documento, trataremos los "triples" y los "quads" por igual: suponemos que un quad es simplemente un triple en un gráfico nombrado o predeterminado.
N3.Parser
transforma el documento de tortuga, trig, n-triples o n-quads en quads a través de una devolución de llamada:
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 ) ;
} ) ;
El primer argumento de la devolución de llamada es un valor de error opcional, el segundo es un quad. Si no hay más quads, la devolución de llamada se invoca por última vez con null
para quad
y un hash de prefijos como tercer argumento.
Alternativamente, se puede suministrar un objeto, donde se usan onQuad
, onPrefix
y onComment
para escuchar quads
, prefixes
y comments
de la siguiente manera:
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 ) ; } ,
} ) ;
Si no se proporcionan devoluciones de llamada, el análisis ocurre sincrónicamente que devuelve una variedad de quads:
const parser = new N3 . Parser ( ) ;
// An array of resultant Quads
const quadArray = parser . parse ( tomAndJerry ) ;
Por defecto, N3.Parser
analiza un superconjunto permisivo de tortuga, trig, n-triples y n-quads.
Para una compatibilidad estricta con cualquiera de esos idiomas, pase un argumento format
en la creación:
const parser1 = new N3 . Parser ( { format : 'N-Triples' } ) ;
const parser2 = new N3 . Parser ( { format : 'application/trig' } ) ;
La notación3 (N3) se admite solo a través del argumento format
:
const parser3 = new N3 . Parser ( { format : 'N3' } ) ;
const parser4 = new N3 . Parser ( { format : 'Notation3' } ) ;
const parser5 = new N3 . Parser ( { format : 'text/n3' } ) ;
Es posible proporcionar el IRI base del documento que desea analizar. Esto se hace pasando un argumento baseIRI
en la creación:
const parser = new N3 . Parser ( { baseIRI : 'http://example.org/' } ) ;
Por defecto, N3.Parser
prefijo etiquetas de nodo en blanco con A b{digit}_
prefijo. Esto se hace para evitar colisiones de nodos en blanco no relacionados que tengan etiquetas idénticas. El argumento del constructor blankNodePrefix
se puede usar para modificar el prefijo o, si se establece en una cadena vacía, deshabilite por completo el prefijo:
const parser = new N3 . Parser ( { blankNodePrefix : '' } ) ;
N3.Parser
puede analizar las transmisiones de node.js a medida que crecen, devolviendo quads tan pronto como estén listos.
const parser = new N3 . Parser ( ) ,
rdfStream = fs . createReadStream ( 'cartoons.ttl' ) ;
parser . parse ( rdfStream , console . log ) ;
N3.StreamParser
es una implementación Node.js Stream y RDF.JS Simpor. Esta solución es ideal si su consumidor es más lento, ya que los datos de origen solo se leen cuando el consumidor está listo.
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 ;
}
Un evento prefix
dedicado señala cada prefijo con prefix
y argumentos term
. Un evento comment
dedicado se puede habilitar estableciendo comments: true
en el constructor n3.streamparser.
N3.Writer
esializa quads como un documento RDF. Escribe quads a través de 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 defecto, N3.Writer
escribe tortuga (o trig si algunos quads están en un gráfico con nombre).
Para escribir N-Triples (o N-Quads) en su lugar, pase un argumento format
en la creación:
const writer1 = new N3 . Writer ( { format : 'N-Triples' } ) ;
const writer2 = new N3 . Writer ( { format : 'application/trig' } ) ;
N3.Writer
también puede escribir quads a una transmisión Node.js a través de 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
es una implementación Node.js Stream y RDF.JS Simpor.
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 ) ;
Es posible que desee usar las anotaciones […]
y la lista (…)
de tortuga y trig. Sin embargo, un escritor de transmisión no puede crearlos automáticamente: las anotaciones de la taquigrafía solo son posibles si los nodos en blanco o los cabezales de la lista no se usan más adelante, lo que solo puede determinarse de manera concluyente al final de la corriente.
Las funciones blank
y list
le permiten crearlas 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
le permite almacenar triples en la memoria y encontrarlos rápidamente.
En este ejemplo, creamos una nueva tienda y agregamos los triples :Pluto a :Dog.
y :Mickey a :Mouse
.
Luego, encontramos triples con :Mickey
como sujeto.
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 ) ;
Si está utilizando varias tiendas, puede reducir el consumo de memoria al permitirles compartir un índice de entidad:
const entityIndex = new N3 . EntityIndex ( ) ;
const store1 = new N3 . Store ( [ ] , { entityIndex } ) ;
const store2 = new N3 . Store ( [ ] , { entityIndex } ) ;
Dataset
Esta tienda se adhiere a la interfaz Dataset
que expone las siguientes propiedades
Atributos:
size
: un entero no negativo que especifica el número de quads en el conjunto.Métodos:
add
: agrega el quad especificado al conjunto de datos. Se ignorarán los quads existentes, como se define en Quad.equals
.delete
: elimina el quad especificado del conjunto de datos.has
: determina si un conjunto de datos incluye un determinado quad.match
: devuelve un nuevo conjunto de datos que se compone de todos los quads en la instancia actual que coincida con los argumentos dados.[Symbol.iterator]
: implementa el protocolo Iterator para permitir la iteración sobre todos quads
en el conjunto de datos como en el ejemplo anterior. El almacén implementa los siguientes métodos de manipulación además de la interfaz de Dataset
estándar (documentación):
addQuad
para insertar un quadaddQuads
para insertar una variedad de quadsremoveQuad
para eliminar un quadremoveQuads
para eliminar una variedad de quadsremove
para eliminar una corriente de quadsremoveMatches
para eliminar todos los quads que coinciden con el patrón dadodeleteGraph
para eliminar todos los quads con el gráfico dadocreateBlankNode
devuelve un identificador de nodo en blanco no utilizadoLa tienda proporciona los siguientes métodos de búsqueda (documentación):
match
Devuelve una transmisión y un generador de quads que coinciden con el patrón dadogetQuads
devuelve una variedad de quads que coinciden con el patrón dadocountQuads
cuenta el número de quads que coinciden con el patrón dadoforEach
ejecuta una devolución de llamada en todos los quads a juegoevery
devuelve si una devolución de llamada en quads coincidentes siempre devuelve verdaderosome
devuelven si una devolución de llamada en quads coincidentes devuelve verdadero al menos una vezgetSubjects
devuelve una variedad de sujetos únicos que ocurren en quads coincidentesforSubjects
ejecuta una devolución de llamada en temas únicos que ocurren en quads a juegogetPredicates
devuelve una variedad de predicados únicos que ocurren en Quad coincidenteforPredicates
ejecuta una devolución de llamada en predicados únicos que ocurren en quads coincidentesgetObjects
devuelve una variedad de objetos únicos que ocurren en Quad coincidenteforObjects
ejecuta una devolución de llamada en objetos únicos que ocurren en quads coincidentesgetGraphs
devuelve una variedad de gráficos únicos que ocurren en Quad coincidenteforGraphs
ejecuta una devolución de llamada en gráficos únicos que ocurren en quads a juego N3.JS admite el razonamiento de la siguiente manera:
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 actualmente solo admite reglas con patrones de gráficos básicos en la premisa y la conclusión. Los empotrados y la cadena hacia atrás no son compatibles. Para un razonador RDF/JS que admite todas las características de razonamiento de notación3, vea Eye-JS.
El analizador y escritor N3.JS es totalmente compatible con las siguientes especificaciones W3C:
Además, el analizador N3.JS también admite la notación3 (N3) (aún no hay especificaciones oficiales).
El analizador y el escritor N3.JS también son totalmente compatibles con las variantes de estrellas RDF de las especificaciones W3C.
El modo predeterminado es permisivo y permite una mezcla de diferentes sintaxis, incluida la estrella RDF. Pase una opción format
al constructor con el nombre o el tipo de mime de un formato para un comportamiento estricto e intolerante a las fallas. Si una cadena de formato contiene star
o *
(por ejemplo, turtlestar
o TriG*
), el soporte RDF-Star para ese formato estará habilitado.
Los submódulos N3.JS son compatibles con las siguientes interfaces rdf.js:
N3.DataFactory
implementa DataFactory
Term
de implementación y uno de NamedNode
, BlankNode
, Literal
, Variable
, DefaultGraph
Term
implementable, Triple
y Quad
N3.StreamParser
implementa Stream
y Sink
N3.StreamWriter
implementa Stream
y Sink
N3.Store
implementa Store
Source
Sink
DatasetCore
La Biblioteca N3.JS tiene derechos de autor de Ruben Verborgh y se libera bajo la licencia MIT.
Las contribuciones son bienvenidas, y los informes de errores o las solicitudes de extracción siempre son útiles. Si planea implementar una característica más grande, es mejor contactarme primero.