{"id":694,"date":"2004-11-05T08:50:58","date_gmt":"2004-11-05T08:50:58","guid":{"rendered":"http:\/\/beta.robertprice.co.uk\/robblog\/2004\/11\/querying_rdf_in_perl_with_rdfstore-shtml\/"},"modified":"2004-11-05T08:50:58","modified_gmt":"2004-11-05T08:50:58","slug":"querying_rdf_in_perl_with_rdfstore-shtml","status":"publish","type":"post","link":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/","title":{"rendered":"Querying RDF In Perl With RDFStore"},"content":{"rendered":"<p>\nApart from <a href=\"http:\/\/search.cpan.org\/~dpokorny\/RDF-Core\/\">RDF::Core<\/a> and <a href=\"http:\/\/search.cpan.org\/~djbeckett\/Redland\/\">Redland<\/a>, another option for parsing and querying <acronym title=\"Resource Description Framework\">RDF<\/acronym> in <a href=\"http:\/\/www.perl.com\/\">Perl<\/a> is <a href=\"http:\/\/search.cpan.org\/~areggiori\/RDFStore\/\">RDFStore<\/a>. This also provides the Perl RDQL::Parser module used by the very useful DBD::RDFStore driver.\n<\/p>\n<p>\nFollowing on from the previous examples showing how to extract information from <a href=\"\/foaf.rdf\">my <acronym title=\"Friend Of A Friend\">FOAF<\/acronym> file<\/a> using RDF::Core (<a href=\"\/robblog\/archive\/2004\/10\/Querying_RDF_In_Perl_With_RDF_Core.shtml\">Query RDF In Perl With RDF::Core<\/a>) and RDF::Redland (<a href=\"\/robblog\/archive\/2004\/10\/Querying_RDF_In_Perl_with_RDF_Redland.shtml\">Querying RDF In Perl With RDF::Redland<\/a>), here I&#8217;ll re-implement the query using RDFStore.\n<\/p>\n<p>\nAs a quick recap from the previous articles, here is the bit of RDF we want to extract information from.\n<\/p>\n<div class=\"code\"><code>&lt;foaf:knows&gt;<br \/>\n&lt;foaf:Person&gt;<br \/>\n&lt;foaf:nick&gt;Cal&lt;\/foaf:nick&gt;<br \/>\n&lt;foaf:name&gt;Cal Henderson&lt;\/foaf:name&gt;<br \/>\n&lt;foaf:mbox_sha1sum&gt;2971b1c2fd1d4f0e8f99c167cd85d522a614b07b&lt;\/foaf:mbox_sha1sum&gt;<br \/>\n&lt;rdfs:seeAlso rdf:resource=\"http:\/\/www.iamcal.com\/foaf.xml\"\/&gt;<br \/>\n&lt;\/foaf:Person&gt;<br \/>\n&lt;\/foaf:knows&gt;<br \/>\n<\/code><\/div>\n<p>\nThe solution used to extract the data from the RDF looks a lot more Perl-like than the previous examples we have seen.\n<\/p>\n<p>\nIf you have ever queried databases using <acronym title=\"Structured Query Language\">SQL<\/acronym> in Perl, then you have certainly come across the powerful <a href=\"http:\/\/search.cpan.org\/~timb\/DBI\/\"><acronym title=\"Database Interface\">DBI<\/acronym> module<\/a>. This abstracts the common database usage making it possible to very easily port your applications between various databases. One of the best things about using RDFStore is that it provides a DBD driver allowing you to use standard DBI methods when querying your RDF data. Unlike other modules that make you create triple stores and factory methods, RDFStore lets that be hidden from you.\n<\/p>\n<p>\nTo start with we&#8217;ll need to create a database handle using DBI and the DBD::RDFStore modules and store it in the variable <var>$dbh<\/var>.\n<\/p>\n<div class=\"code\"><code>my $dbh = DBI-&gt;connect(\"DBI:RDFStore:\");<br \/>\n<\/code><\/div>\n<p>\nThis creates a database on the fly, but we can connect to an existing database on a local or remote server if we so wished.\n<\/p>\n<p>\nNow we need to create our RDQL query. It looks very similar to the query we used in the Redland example.\n<\/p>\n<div class=\"code\"><code>my $query = $dbh-&gt;prepare(&lt;&lt;QUERY);<br \/>\nSELECT ?name ?nick ?seeAlso ?mbox_sha1sum<br \/>\nFROM &lt;file:foaf.rdf&gt;<br \/>\nWHERE<br \/>\n(?x &lt;rdf:type&gt; &lt;foaf:Person&gt;),<br \/>\n(?x &lt;foaf:name&gt; ?name)<br \/>\n(?x &lt;foaf:nick&gt; ?nick)<br \/>\n(?x &lt;rdfs:seeAlso&gt; ?seeAlso)<br \/>\n(?x &lt;foaf:mbox_sha1sum&gt; ?mbox_sha1sum)<br \/>\nAND<br \/>\n(?nick eq 'Cal')<br \/>\nUSING<br \/>\nfoaf for &lt;http:\/\/xmlns.com\/foaf\/0.1\/&gt;,<br \/>\nQUERY<br \/>\n<\/code><\/div>\n<p>\nHere we&#8217;re selecting the values the name, nick, seeAlso and mbox_sha1sum triples for a Person with the nick of Cal. We&#8217;ve explicitly set where our triples come from using the <code>FROM<\/code> clause. In this case, it&#8217;s the file <var>foaf.rdf<\/var>, which contains my FOAF information.\n<\/p>\n<p>\nWe have the query in the variable <var>$query<\/var>, so lets execute it.\n<\/p>\n<div class=\"code\"><code>$query-&gt;execute();<br \/>\n<\/code><\/div>\n<p>\nWe can use standard DBI methods to fetch the data from our query. Here I&#8217;m going to create some bound variables to keep any matching data in.\n<\/p>\n<div class=\"code\"><code>my ($name, $seeAlso, $mbox_sha1sum, $nick);<br \/>\n$query-&gt;bind_columns($name, $nick, $seeAlso, $mbox_sha1sum);<br \/>\n<\/code><\/div>\n<p>\nNow we just have to fetch each row that matches our query and print them out.\n<\/p>\n<div class=\"code\"><code>while ($query-&gt;fetch()) {<br \/>\nprint $name-&gt;toString, \"n\";<br \/>\nprint $nick-&gt;toString, \"n\";<br \/>\nprint $seeAlso-&gt;toString, \"n\";<br \/>\nprint $mbox_sha1sum-&gt;toString, \"n\";<br \/>\n}<br \/>\n<\/code><\/div>\n<p>\nThe values returned are either RDFStore::Literal or RDFStore::Resource objects, so we have to use their <code>toString<\/code> methods to print them.\n<\/p>\n<p>\nTo tidy up, we&#8217;ll finish our query and disconnect from our database.\n<\/p>\n<div class=\"code\"><code>$query-&gt;finish;<br \/>\n$dbh-&gt;disconnect;<br \/>\n<\/code><\/div>\n<p>\nThat&#8217;s it! It really is as simple as that.\n<\/p>\n<p>\nLet&#8217;s put this all together now to produce our final example code listing.\n<\/p>\n<div class=\"code\"><code>#!\/usr\/bin\/perl -w<br \/>\n## An example showing how to use RDFStore and RDQL::Parser to<br \/>\n## extract information from a FOAF file.<br \/>\n## Copyright 2004 - Robert Price - http:\/\/www.robertprice.co.uk\/<br \/>\nuse strict;<br \/>\nuse DBI;<br \/>\n## create a DBI connection to our NodeFactory.<br \/>\nmy $dbh = DBI-&gt;connect(\"DBI:RDFStore:\");<br \/>\n## prepare our query.<br \/>\nmy $query = $dbh-&gt;prepare(&lt;&lt;QUERY);<br \/>\nSELECT ?name ?nick ?seeAlso ?mbox_sha1sum<br \/>\nFROM &lt;file:foaf.rdf&gt;<br \/>\nWHERE<br \/>\n(?x &lt;rdf:type&gt; &lt;foaf:Person&gt;),<br \/>\n(?x &lt;foaf:name&gt; ?name)<br \/>\n(?x &lt;foaf:nick&gt; ?nick)<br \/>\n(?x &lt;rdfs:seeAlso&gt; ?seeAlso)<br \/>\n(?x &lt;foaf:mbox_sha1sum&gt; ?mbox_sha1sum)<br \/>\nAND<br \/>\n(?nick eq 'Cal')<br \/>\nUSING<br \/>\nfoaf for &lt;http:\/\/xmlns.com\/foaf\/0.1\/&gt;,<br \/>\nQUERY<br \/>\n## execute the query.<br \/>\n$query-&gt;execute();<br \/>\n## define some holding variables and bind them to our query results.<br \/>\nmy ($name, $seeAlso, $mbox_sha1sum, $nick);<br \/>\n$query-&gt;bind_columns($name, $nick, $seeAlso, $mbox_sha1sum);<br \/>\n## while we have results being returned...<br \/>\nwhile ($query-&gt;fetch()) {<br \/>\n## print out the values.<br \/>\n## As these can be RDFStore::Literal or RDFStore::Resource's we<br \/>\n## need to use the toString method of these objects to print.<br \/>\nprint $name-&gt;toString, \"n\";<br \/>\nprint $nick-&gt;toString, \"n\";<br \/>\nprint $seeAlso-&gt;toString, \"n\";<br \/>\nprint $mbox_sha1sum-&gt;toString, \"n\";<br \/>\n}<br \/>\n## end the query and disconnect.<br \/>\n$query-&gt;finish;<br \/>\n$dbh-&gt;disconnect;<br \/>\n<\/code><\/div>\n<p>\nIn conclusion, RDFStore provides a very clean and Perlish interface to querying RDF data. The code implements a DBD module allowing standard DBI methods to be used, making it quick and simple for Perl developers to learn and use effectively.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apart from RDF::Core and Redland, another option for parsing and querying RDF in Perl is RDFStore. This also provides the Perl RDQL::Parser module used by the very useful DBD::RDFStore driver. Following on from the previous examples showing how to extract information from my FOAF file using RDF::Core (Query RDF In Perl With RDF::Core) and RDF::Redland &hellip; <a href=\"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Querying RDF In Perl With RDFStore&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[2],"tags":[17,21,47,56],"class_list":["post-694","post","type-post","status-publish","format-standard","hentry","category-dev","tag-dev","tag-foaf","tag-perl","tag-rdf"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Querying RDF In Perl With RDFStore - Robert Price<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Querying RDF In Perl With RDFStore - Robert Price\" \/>\n<meta property=\"og:description\" content=\"Apart from RDF::Core and Redland, another option for parsing and querying RDF in Perl is RDFStore. This also provides the Perl RDQL::Parser module used by the very useful DBD::RDFStore driver. Following on from the previous examples showing how to extract information from my FOAF file using RDF::Core (Query RDF In Perl With RDF::Core) and RDF::Redland &hellip; Continue reading &quot;Querying RDF In Perl With RDFStore&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/\" \/>\n<meta property=\"og:site_name\" content=\"Robert Price\" \/>\n<meta property=\"article:published_time\" content=\"2004-11-05T08:50:58+00:00\" \/>\n<meta name=\"author\" content=\"rob\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"rob\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/\"},\"author\":{\"name\":\"rob\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"headline\":\"Querying RDF In Perl With RDFStore\",\"datePublished\":\"2004-11-05T08:50:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/\"},\"wordCount\":482,\"keywords\":[\"Dev\",\"FOAF\",\"Perl\",\"RDF\"],\"articleSection\":[\"Dev\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/\",\"name\":\"Querying RDF In Perl With RDFStore - Robert Price\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\"},\"datePublished\":\"2004-11-05T08:50:58+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/querying_rdf_in_perl_with_rdfstore-shtml\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Querying RDF In Perl With RDFStore\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#website\",\"url\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/\",\"name\":\"Robert Price\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.robertprice.co.uk\\\/robblog\\\/#\\\/schema\\\/person\\\/fac6d5b076e0e14e1fb13e15b542a6c5\",\"name\":\"rob\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g\",\"caption\":\"rob\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Querying RDF In Perl With RDFStore - Robert Price","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/","og_locale":"en_GB","og_type":"article","og_title":"Querying RDF In Perl With RDFStore - Robert Price","og_description":"Apart from RDF::Core and Redland, another option for parsing and querying RDF in Perl is RDFStore. This also provides the Perl RDQL::Parser module used by the very useful DBD::RDFStore driver. Following on from the previous examples showing how to extract information from my FOAF file using RDF::Core (Query RDF In Perl With RDF::Core) and RDF::Redland &hellip; Continue reading \"Querying RDF In Perl With RDFStore\"","og_url":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/","og_site_name":"Robert Price","article_published_time":"2004-11-05T08:50:58+00:00","author":"rob","twitter_card":"summary_large_image","twitter_misc":{"Written by":"rob","Estimated reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/#article","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/"},"author":{"name":"rob","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"headline":"Querying RDF In Perl With RDFStore","datePublished":"2004-11-05T08:50:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/"},"wordCount":482,"keywords":["Dev","FOAF","Perl","RDF"],"articleSection":["Dev"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/","url":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/","name":"Querying RDF In Perl With RDFStore - Robert Price","isPartOf":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website"},"datePublished":"2004-11-05T08:50:58+00:00","author":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5"},"breadcrumb":{"@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.robertprice.co.uk\/robblog\/querying_rdf_in_perl_with_rdfstore-shtml\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.robertprice.co.uk\/robblog\/"},{"@type":"ListItem","position":2,"name":"Querying RDF In Perl With RDFStore"}]},{"@type":"WebSite","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#website","url":"https:\/\/www.robertprice.co.uk\/robblog\/","name":"Robert Price","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.robertprice.co.uk\/robblog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Person","@id":"https:\/\/www.robertprice.co.uk\/robblog\/#\/schema\/person\/fac6d5b076e0e14e1fb13e15b542a6c5","name":"rob","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0eb511179100a4e968abc70403e33686e6ab3e992e392bedd2ccac01da666c?s=96&d=mm&r=g","caption":"rob"}}]}},"_links":{"self":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/694","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/comments?post=694"}],"version-history":[{"count":0,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/posts\/694\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/media?parent=694"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/categories?post=694"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.robertprice.co.uk\/robblog\/wp-json\/wp\/v2\/tags?post=694"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}