5

I am starting to use the rdflib library for dealing with rdf data in Python. At the moment, I want to create a .n3 file of some rdf graph that looks like this:

@prefix ns1: <http://some.namespace/with/name#> .
@prefix ns2: <http://second.namespace/some/name#>
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<my_example> ns1:annotated_with [ ns1:annotation
        ns2: annotation_value> ] ;
    ns1:name "myname" .

That is, there is one example in this graph which is called my_example, which has a name "myname". This example is annotated with an object whose annotation value is annotation value. I wanted to construct this example in Python like so:

import rdflib

gg=rdflib.graph.Graph()
ns1 = rdflib.Namespace('http://some.namespace/with/name#')
ns2 = rdflib.Namespace('http://second.namespace/some/name#')
u = rdflib.term.URIRef('my_example')
gg.add((u, ns1.name, rdflib.Literal('myname')))
blank = rdflib.BNode()
gg.add((u, ns1.annotated_with, blank))
gg.add((blank, ns1.annotation, ns2.annotation_value))

print gg.serialize(format='n3')

Which should, in my oppinion, produce the correct result, and, in a way, it does. The result of the code above is a n3 string that looks like this:

@prefix ns1: <http://some.namespace/with/name#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .

<my_example> ns1:annotated_with [ ns1:annotation <http://second.namespace/some/name#annotation_value> ] ;
    ns1:name "myname" .

Which is close, but I don't understand why rdflib did not define, in the beginning of the file, the second namespace I am using. Is there a way to force it to do this?

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
5xum
  • 5,250
  • 8
  • 36
  • 56
  • 2
    Is this answered by [RDFLib: Namespace prefixes in XML serialization](http://stackoverflow.com/q/4427607/1281433)? `ns1` is an automatically generated name in the serialization; it doesn't have anything do with the fact that your variable is named `ns1` (I expect). You still need to do `gg.bind('ns2', URIRef('http://second.namespace/some/name#'))` to bind `ns2` (and you *should* do the same for the first namespace, too). – Joshua Taylor Feb 13 '15 at 19:33
  • 1
    I guess there's still the question of "which namespaces does rdflib try to automatically generate prefixes for?" That could be something as simple as maybe it only does that for IRIs appearing in the subject position; who knows. – Joshua Taylor Feb 13 '15 at 19:35
  • @JoshuaTaylor Thank you for the provided link. I don't think my answer is a precise duplicate, but the answer there may prove useless, especially the use of the `bind` command. I will have a look and edit my question with the results. – 5xum Feb 13 '15 at 21:31
  • Why would it be useless? Wouldn't using `bind` be exactly how to "Force rdflib to define a namespace", which was the question? – Joshua Taylor Feb 13 '15 at 22:02
  • 3
    @JoshuaTaylor This was just the worst typo ever. I meant to write **useful** (honestly, I did!). – 5xum Feb 13 '15 at 22:29
  • No worries! I hope this ends up being useful. :) – Joshua Taylor Feb 15 '15 at 21:34

1 Answers1

5

The method bind is what I was looking for. It was used in the related question and is also useful here.

Adding the lines

gg.bind('myprefix1', ns1)
gg.bind('myprefix2', ns1)

results in what I needed.

5xum
  • 5,250
  • 8
  • 36
  • 56