2011-01-15 6 views
4

rdf 목록의 구성원에 액세스하는 가장 좋은 방법은 무엇입니까? 나는 rdflib (python)을 사용하고 있지만 평범한 SPARQL에서 주어진 답은 ok이다. (이 유형의 대답은 rdfextras, rdflib 도우미 라이브러리를 통해 사용할 수있다.)rdflib (또는 일반 sparql)을 사용하여 rdf 목록의 구성원에 액세스하는 방법

내가 (일부 필드는 간결 제거되었습니다) Zotero에 의해 생산 된 RDF의 특정 저널 기사의 저자에 액세스하려고 해요 :

<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> 

답변

6

RDF 용기는, 아주 성가신 일반에 통증이 있습니다 그들을 처리하십시오. 나는 SPARQL과 다른 재치 SPARQL없이 두 개의 솔루션을 게시하려고한다. 개인적으로 나는 SPARQL을 사용하는 두 번째 것을 선호합니다.

예 1 : 귀하의 경우처럼 특정 기사에 대한 모든 저자를 얻으려면

SPARQL없이 당신은 내가 아래에 게시하고있는 코드와 같은 뭔가를 할 수 있습니다.

설명을 추가하여 자체 설명합니다. 가장 중요한 비트 은이 그래프 기능을 기본으로 사용하는 g.triple(triple_pattern)입니다. rdflib 그래프를 필터링하고 필요한 트리플 패턴을 검색 할 수 있습니다. 서열은 다음 구문 분석 형태의 술어 : 당신은 정렬 할 필요가 있으므로

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

가 생성이 임의의 순서로 검색 rdflib RDF의이

그들에게 을 올바른 순서로 트래버스합니다.

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 

이 예에서는 SPARQL을 사용하지 않고이를 수행하는 방법을 보여줍니다.

예 2

지금 똑같은 예를 사용하지만 SPARQL있다 SPARQL로.

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]) 

라이브러리에서 자체적으로 처리하지 않기 때문에 정렬 작업을 수행해야합니다. 쿼리에서 변수 seq_index은 시퀀스 순서에 대한 정보를 포함하고 람다 함수에서 정렬을 수행하는 술어를 포함하는 조건자를 보유합니다.

+0

감사합니다. 비슷한 기본 SPARQL 질문이 많습니다. 나는 이것에 대해 꽤 많은 시간을 보냈지 만 어떤 직접적인 대답도 찾을 수 없었다. SPARQL을 다루는 훌륭한 튜토리얼이나 레퍼런스에 대해 알고 계십니까? (기본과 철학을 뛰어 넘는 수준에서) – tjb

+1

Jena의 http://jena.sourceforge.net/ARQ/Tutorial/ (비록 Java/Jena가 더 많고 RDFLIB가 아니더라도)이 꽤 좋다고 생각합니다.파이썬에 대한 추가 정보 시맨틱 웹 프로그래밍 http://oreilly.com/catalog/9780596153823을 권해드립니다. 어쨌든 SPARQL로 문제가 생기면 게시하고 도와 드리겠습니다. –

+0

감사합니다. 앞으로 더 많은 질문이 올 것이라고 확신합니다. – tjb

0

더 최신 버전의 RDFLib에서는보다 간소화 된 방식으로 콜렉션에 액세스 할 수 있습니다. 순차적으로 멤버에 프로그래밍 방식으로 액세스하려면 다음 코드를 사용하여 수행 할 수 있습니다.

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