2011-01-15 25 views
4

Wie ist der beste Weg, um die Mitglieder einer RFD-Liste zugreifen? Ich benutze rdflib (python), aber eine Antwort in einfachen SPARQL ist auch in Ordnung (diese Art von Antwort kann durch rdfextras, eine rdflib-Helfer-Bibliothek verwendet werden).Zugriff auf Mitglieder einer RFD-Liste mit RDFLIB (oder Plain SPARQL)

Ich versuche, die Autoren eines bestimmten Zeitschriftenartikel in rdf von Zotero produziert für den Zugriff auf (einige Felder der Kürze halber entfernt wurde):

<rdf:RDF 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 
xmlns:z="http://www.zotero.org/namespaces/export#" 
xmlns:dcterms="http://purl.org/dc/terms/" 
xmlns:bib="http://purl.org/net/biblio#" 
xmlns:foaf="http://xmlns.com/foaf/0.1/" 
xmlns:dc="http://purl.org/dc/elements/1.1/" 
xmlns:prism="http://prismstandard.org/namespaces/1.2/basic/" 
xmlns:link="http://purl.org/rss/1.0/modules/link/"> 
    <bib:Article rdf:about="http://www.ncbi.nlm.nih.gov/pubmed/18273724"> 
     <z:itemType>journalArticle</z:itemType> 
     <dcterms:isPartOf rdf:resource="urn:issn:0954-6634"/> 
     <bib:authors> 
      <rdf:Seq> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Lee</foaf:surname> 
         <foaf:givenname>Hyoun Seung</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Lee</foaf:surname> 
         <foaf:givenname>Jong Hee</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Ahn</foaf:surname> 
         <foaf:givenname>Gun Young</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Lee</foaf:surname> 
         <foaf:givenname>Dong Hun</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Shin</foaf:surname> 
         <foaf:givenname>Jung Won</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Kim</foaf:surname> 
         <foaf:givenname>Dong Hyun</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
       <rdf:li> 
        <foaf:Person> 
         <foaf:surname>Chung</foaf:surname> 
         <foaf:givenname>Jin Ho</foaf:givenname> 
        </foaf:Person> 
       </rdf:li> 
      </rdf:Seq> 
     </bib:authors> 

     <dc:title>Fractional photothermolysis for the treatment of acne scars: a report of 27 Korean patients</dc:title> 
     <dcterms:abstract>OBJECTIVES: Atrophic post-acne scarring remains a therapeutically challe *CUT*, erythema and edema. CONCLUSIONS: The 1550-nm erbium-doped FP is associated with significant patient-reported improvement in the appearance of acne scars, with minimal downtime.</dcterms:abstract> 
     <bib:pages>45-49</bib:pages> 
     <dc:date>2008</dc:date> 
     <z:shortTitle>Fractional photothermolysis for the treatment of acne scars</z:shortTitle> 
     <dc:identifier> 
      <dcterms:URI> 
       <rdf:value>http://www.ncbi.nlm.nih.gov/pubmed/18273724</rdf:value> 
      </dcterms:URI> 
     </dc:identifier> 
     <dcterms:dateSubmitted>2010-12-06 11:36:52</dcterms:dateSubmitted> 
     <z:libraryCatalog>NCBI PubMed</z:libraryCatalog> 
     <dc:description>PMID: 18273724</dc:description> 
    </bib:Article> 
    <bib:Journal rdf:about="urn:issn:0954-6634"> 
     <dc:title>The Journal of Dermatological Treatment</dc:title> 
     <prism:volume>19</prism:volume> 
     <prism:number>1</prism:number> 
     <dcterms:alternative>J Dermatolog Treat</dcterms:alternative> 
     <dc:identifier>DOI 10.1080/09546630701691244</dc:identifier> 
     <dc:identifier>ISSN 0954-6634</dc:identifier> 
    </bib:Journal> 

Antwort

6

rdf Behälter ein Schmerz im Allgemeinen sind, ziemlich ärgerlich mit ihnen umgehen. Ich poste zwei Lösungen, eine ohne SPARQL und eine andere mit SPARQL. Persönlich bevorzuge ich die zweite, die SPARQL verwendet.

Beispiel 1: ohne SPARQL

alle für einen bestimmten Artikel wie in Ihrem Fall die Autoren Um Ihnen so etwas wie der Code tun könnte ich unten bin Entsendung.

Ich habe Kommentare hinzugefügt, so dass es sich selbst erklärt. Das wichtigste Bit ist die Verwendung von g.triple(triple_pattern) mit dieser Grafikfunktion im Grunde Sie können ein rdflib-Diagramm filtern und nach den dreifachen Mustern suchen, die Sie benötigen.

Wenn ein rdf: Seq dann Prädikate der Form analysiert wird:

http://www.w3.org/1999/02/22-rdf-syntax-ns#_1

http://www.w3.org/1999/02/22-rdf-syntax-ns#_2

http://www.w3.org/1999/02/22-rdf-syntax-ns#_3

erstellt werden, sie in zufälliger Reihenfolge rdflib abrufen, so dass Sie sortieren müssen sie zu durchlaufen sie in der richtigen Reihenfolge.

import rdflib 

RDF = rdflib.namespace.RDF 

#Parse the file 
g = rdflib.Graph() 
g.parse("zot.rdf") 

#So that we are sure we get something back 
print "Number of triples",len(g) 

#Couple of handy namespaces to use later 
BIB = rdflib.Namespace("http://purl.org/net/biblio#") 
FOAF = rdflib.Namespace("http://xmlns.com/foaf/0.1/") 

#Author counter to print at the bottom 
i=0 

#Article for wich we want the list of authors 
article = rdflib.term.URIRef("http://www.ncbi.nlm.nih.gov/pubmed/18273724") 

#First loop filters is equivalent to "get all authors for article x" 
for triple in g.triples((article,BIB["authors"],None)): 

    #This expresions removes the rdf:type predicate cause we only want the bnodes 
    # of the form http://www.w3.org/1999/02/22-rdf-syntax-ns#_SEQ_NUMBER 
    # where SEQ_NUMBER is the index of the element in the rdf:Seq 
    list_triples = filter(lambda y: RDF['type'] != y[1], g.triples((triple[2],None,None))) 

    #We sort the authors by the predicate of the triple - order in sequences do matter ;-) 
    # so "http://www.w3.org/1999/02/22-rdf-syntax-ns#_435"[44:] returns 435 
    # and since we want numberic order we do int(x[1][44:]) - (BTW x[1] is the predicate) 
    authors_sorted = sorted(list_triples,key=lambda x: int(x[1][44:])) 

    #We iterate the authors bNodes and we get surname and givenname 
    for author_bnode in authors_sorted: 
     for x in g.triples((author_bnode[2],FOAF['surname'],None)): 
      author_surname = x[2] 
     for y in g.triples((author_bnode[2],FOAF['givenname'],None)): 
      author_name = y[2] 
     print "author(%s): %s %s"%(i,author_name,author_surname) 
     i += 1 

Dieses Beispiel zeigt, wie Sie dies tun, ohne SPARQL zu verwenden.

Beispiel 2: SPARQL

nun genau dort das gleiche Beispiel ist aber SPARQL verwenden.

rdflib.plugin.register('sparql', rdflib.query.Processor, 
         'rdfextras.sparql.processor', 'Processor') 
rdflib.plugin.register('sparql', rdflib.query.Result, 
         'rdfextras.sparql.query', 'SPARQLQueryResult') 

query = """ 
SELECT ?seq_index ?name ?surname WHERE { 
    <http://www.ncbi.nlm.nih.gov/pubmed/18273724> bib:authors ?seq . 
    ?seq ?seq_index ?seq_bnode . 
    ?seq_bnode foaf:givenname ?name . 
    ?seq_bnode foaf:surname ?surname . 
} 
""" 
for row in sorted(g.query(query, initNs=dict(rdf=RDF,foaf=FOAF,bib=BIB)), 
                key=lambda x:int(x[0][44:])): 
    print "Author(%s) %s %s"%(row[0][44:],row[1],row[2]) 

Wie es zeigt, müssen wir immer noch die Sortierung tun, weil die Bibliothek nicht selbst damit umgehen kann. In der Abfrage enthält die Variable seq_index das Prädikat, das die Information über die Reihenfolge der Reihenfolge enthält und das die Sortierung in der Lambda-Funktion ausführt.

+0

Danke, habe ich eine Menge von ähnlichen Grund SPARQL Fragen. Ich verbrachte eine ganze Weile damit, zu googeln, konnte aber keine direkte Antwort finden. Kennen Sie ein gutes Tutorial oder eine Referenz, die sich mit SPARQL beschäftigt (auf einer Ebene jenseits der Grundlagen und unter der Philosophie)? – tjb

+1

Der eine, den ich denke, ist ziemlich gut ist http://jena.sourceforge.net/ARQ/Tutorial/ Jena (obwohl mehr Java/Jena ist und nicht für RDFLIB).Mehr zu python empfehle ich das Buch Programming the Semantic Web http://oreilly.com/catalog/9780596153823. Wenn Sie Probleme mit SPARQLs haben, dann posten Sie diese und ich werde Ihnen helfen. –

+0

Danke, ich bin mir sicher, dass weitere Fragen kommen werden – tjb

0

In neueren Versionen von RDFLib können Sammlungen in einer optimierteren Art und Weise abgerufen werden. Programatically Zugriff auf Elemente in einer Sequenz können nun die Seq-Klasse erreicht werden:

from rdflib import * 
from rdflib.graph import Seq 
from rdflib.namespace import FOAF 
BIB = Namespace("http://purl.org/net/biblio#") 

# Load data 
g = Graph() 
g.parse(file=open("./zotero.rdf", "r"), format="application/rdf+xml") 

# Get the first resource linked to article via bib:authors 
article = URIRef("http://www.ncbi.nlm.nih.gov/pubmed/18273724") 
authors = g.objects(article, BIB.authors).__next__() 
i = 1 
for author in Seq(g, authors): 
    givenname = g.triples((author, FOAF.givenname, None)).__next__()[2] 
    surname = g.triples((author, FOAF.surname, None)).__next__()[2] 
    print("%i: %s %s" % (i, str(givenname), str(surname))) 
    i += 1