jgreve
jgreve

Reputation: 1253

Using SPARQL's URI( ) fn w/PREFIX & suffix containing slashes?

I want to use a PREFIX to simplify URI creation. Will welcome any advice that helps me build a mental model of what PREFIX is doing in a SPARQL query - it doesn't seem to a simple key/value replacement.

Here are some examples of what have tried.

working

This works as expected and does what I want, except for not using a PREFIX.

SELECT * WHERE {
    BIND ( URI("http:://www.foo.com/bar/01/grik/234") as ?s ) # (a) works fine
    ?s a ?o .
    # Here (a) works as expected. I'm binding ?s to a specific URI
    # for testing because otherwise it runs too long to debug my query logic.
}
LIMIT 10

My failed PREFIX attempts

My actual prefix URI fragment is longer but this example shows the idea.

I want to put the first part of the above URI, http:://www.foo.com/bar/, in a PREFIX and use 01/grik/234 as a suffix.

Variations of this return nothing or error out on URI composition:

PREFIX foo: <http:://www.foo.com/bar/>
SELECT * WHERE {
    # I'm just running run one of these BIND statements
    # at a time; listing all of them here for easier visual comparison.
    # BIND ( URI(foo:01/grik/234) as ?s )                   # (b) Lexical error. Encountered "/" after "grik"
    # BIND ( URI(foo:"01/grik/234") as ?s )                 # (c) Encountered " <STRING_LITERAL2> "\01/grik/234"\""
    # BIND ( URI(foo:URI("01/grik/234")) as ?s )            # (d) Encountered "/" after "01"
    # BIND ( URI(foo:ENCODE_FOR_URI("01/grik/234")) as ?s ) # (e) Encountered "/" after "01"
    # BIND( URI(foo:ENCODE_FOR_URI("01/grik/234")) as ?s )  # (f) WARN  URI <http:://www.foo.com/bar/ENCODE_FOR_URI> has no registered function factory
    ?s a ?o .
}
LIMIT 10

Upvotes: 1

Views: 680

Answers (1)

UninformedUser
UninformedUser

Reputation: 8465

You're trying to use a IRI in its prefixed name form. The W3C SPARQL recommendation contains the following section

4.1.1.1 Prefixed Names

The PREFIX keyword associates a prefix label with an IRI. A prefixed name is a prefix label and a local part, separated by a colon ":". A prefixed name is mapped to an IRI by concatenating the IRI associated with the prefix and the local part. The prefix label or the local part may be empty. Note that SPARQL local names allow leading digits while XML local names do not. SPARQL local names also allow the non-alphanumeric characters allowed in IRIs via backslash character escapes (e.g. ns:id\=123). SPARQL local names have more syntactic restrictions than CURIEs.

Given that / is a non-alphanumeric character, the most important part here is

SPARQL local names also allow the non-alphanumeric characters allowed in IRIs via backslash character escapes (e.g. ns:id\=123).

Long story short, your query should be

PREFIX foo: <http:://www.foo.com/bar/>

SELECT * WHERE {  
    BIND ( URI(foo:01\/grik\/234) as ?s )
    ?s a ?o .
}
LIMIT 10

Upvotes: 4

Related Questions