2013-03-02 13 views
7

Ho un file nel formato .ttl. Dispone di 4 attributi/colonne contenenti quadruple del seguente formato:Come analizzare i file .ttl con RDFLib?

  1. (id, student_name, student_address, student_phoneno).
  2. (id, faculty_name, faculty_address, faculty_phoneno).

So come analizzare .n3 forma triple con RDFLib;

from rdflib import Graph 
g = Graph() 
g.parse("demo.nt", format="nt") 

ma non sono sicuro di come analizzare questi quadrupli.

Il mio intento è analizzare ed estrarre tutte le informazioni relative a un determinato ID. L'ID può essere lo stesso sia per gli studenti che per i docenti.

Come posso utilizzare RDFLib per elaborare questi quadrupli e utilizzarlo per l'aggregazione basata su id?

Esempio frammento .ttl di file:

#@ <id1> 
<Alice> <USA> <12345> 

#@ <id1> 
<Jane> <France> <78900> 
+0

è il 'ttl' riferimento nella discussione la stessa di quella a cui fa riferimento il tag? –

+0

Che cos'è il modulo TTL? –

+1

Penso che sia [Turtle - Terse RDF Triple Language] (http://www.w3.org/TeamSubmission/turtle/) – Abhijit

risposta

0

Sembra che ci sia attualmente nessuna tale presenti libreria per analizzare il Turtle - Terse RDF Triple Language

Come già sapete la grammatica, la soluzione migliore è quella di utilizzare PyParsing per primo creare una grammatica e quindi analizzare il file.

Vorrei anche suggerire di adattare il seguente EBNF implementation per il vostro bisogno

0

Si può fare come serpenti e caffè suggerisce, avvolgere solo quella funzione (o il suo codice) in un ciclo con le dichiarazioni di resa. Questo crea un generatore, che può essere chiamato in modo iterativo per creare al volo le parole della riga successiva. Supponendo che si andavano a scrivere queste in un file CSV, ad esempio, utilizzando parse_to_dict Snakes':

import re 
import csv 

writer = csv.DictWriter(open(outfile, "wb"), fieldnames=["id", "name", "address", "phone"]) 
# or whatever 

È possibile creare un generatore in funzione o con una comprensione in linea:

def dict_generator(lines): 
    for line in lines: 
     yield parse_to_dict(line) 

--o -

dict_generator = (parse_to_dict(line) for line in lines) 

Questi sono praticamente equivalenti. A questo punto puoi ottenere una riga analizzata in dict chiamando lo dict_generator.next(), e magicamente ne prendi uno alla volta, senza coinvolgere la RAM aggiuntiva.

Se si dispone di 16 concerti di dati grezzi, si potrebbe prendere in considerazione l'idea di fare in modo che anche un generatore inserisca le linee. Sono davvero utili.

Maggiori informazioni su generatori da SO e alcuni documenti: What can you use Python generator functions for? http://wiki.python.org/moin/Generators

+0

La linea di serpenti e caffè..parse_to_dict non c'è e ho dimenticato cosa intendeva fare quella linea –

6

Turtle è un sottoinsieme della sintassi Notation 3 così rdflib dovrebbe essere in grado di analizzare utilizzando format='n3'. Controllare se rdflib conserva i commenti (id s sono specificati nei commenti (#...) nell'esempio).In caso contrario e il formato di input è semplice come mostrato nel tuo esempio, allora si potrebbe analizzare manualmente:

import re 
from collections import namedtuple 
from itertools import takewhile 

Entry = namedtuple('Entry', 'id name address phone') 

def get_entries(path): 
    with open(path) as file: 
     # an entry starts with `#@` line and ends with a blank line 
     for line in file: 
      if line.startswith('#@'): 
       buf = [line] 
       buf.extend(takewhile(str.strip, file)) # read until blank line 
       yield Entry(*re.findall(r'<([^>]+)>', ''.join(buf))) 

print("\n".join(map(str, get_entries('example.ttl')))) 

uscita:

Entry(id='id1', name='Alice', address='USA', phone='12345') 
Entry(id='id1', name='Jane', address='France', phone='78900') 

Per salvare voci a un db:

import sqlite3 

with sqlite3.connect('example.db') as conn: 
    conn.execute('''CREATE TABLE IF NOT EXISTS entries 
      (id text, name text, address text, phone text)''') 
    conn.executemany('INSERT INTO entries VALUES (?,?,?,?)', 
        get_entries('example.ttl')) 

Per raggruppare per id se avete bisogno di postelaborazione in Python:

import sqlite3 
from itertools import groupby 
from operator import itemgetter 

with sqlite3.connect('example.db') as c: 
    rows = c.execute('SELECT * FROM entries ORDER BY id LIMIT ?', (10,)) 
    for id, group in groupby(rows, key=itemgetter(0)): 
     print("%s:\n\t%s" % (id, "\n\t".join(map(str, group)))) 

uscita:

id1: 
    ('id1', 'Alice', 'USA', '12345') 
    ('id1', 'Jane', 'France', '78900')