SPARQL query to get all class label with namespace prefix defined

10,882

Solution 1

You want to add a URI prefix to the front of a label string?

I think you might be confused about what URI prefixes do. They're just shorthand for full URIs, and aren't part of the URI, and they don't have any bearing on strings.

You can do something like what you want with

SELECT ?class (CONCAT("ex:", ?classLabel) AS ?label
WHERE {
   ?class rdf:type rdfs:Class.
   ?class rdfs:label ?classLabel.
}

But the prefix won't depend on the prefix of the URI.

You could have a chain of IF()s that tests the starting characters of STR(?class), but it will get ugly quickly:

BIND(IF(STRSTARTS(STR(?class), "http://example.com/"), "ex:", "other:") as ?prefix)

then

SELECT ... (CONCAT(?prefix, ?classLabel) AS ?label

There's almost certainly an easier way to get what you want than doing it in SPARQL though :)

Solution 2

I agree with the other answers that say you're trying to do a strange thing, at least as it's stated in the question. Associating the prefix with the rdfs:label isn't all that useful, since the resulting string may or may not represent the actual URI of the class. Assuming that what you're trying to do is actually figure out a prefixed name for a URI given some set of prefix definitions, you can do this in SPARQL without needing lots of nested IFs; you can do it by using a VALUES and a FILTER.

Given data like this, in which a number of classes are defined (I don't define any labels here, since they're not necessary for this example),

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ex1: <http://example1.com/> .
@prefix ex2: <http://example2.com/> .
@prefix ex3: <http://example3.com/> .
@prefix ex4: <http://example4.com/> .

ex1:A a rdfs:Class .
ex1:B1 a rdfs:Class .

ex2:A a rdfs:Class .
ex2:B2 a rdfs:Class .

ex3:A a rdfs:Class .
ex3:B3 a rdfs:Class .

ex3:A a rdfs:Class .
ex3:B4 a rdfs:Class .

ex4:A a rdfs:Class .
ex4:B4 a rdfs:Class .

you can write a query like this that selects all classes, checks whether their URI begins with one of a number of defined namespaces, and if so, returns the class and the prefixed form:

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> 

select ?class (group_concat(?prefixedName ; separator = "") as ?prefName) where {
  values (?prefix ?ns) { 
    ( "ex1:" <http://example1.com/> )
    ( "ex2:" <http://example2.com/> )
    ( "ex3:" <http://example3.com/> )
  }
  ?class a rdfs:Class .
  bind( if( strStarts( str(?class), str(?ns) ),
            concat( ?prefix, strafter( str(?class), str(?ns) )),
            "" ) 
        as ?prefixedName )
}
group by ?class
order by ?class

which produces as results:

$ arq --data data.n3 --query query.sparql
---------------------------------------
| class                    | prefName |
=======================================
| <http://example1.com/A>  | "ex1:A"  |
| <http://example1.com/B1> | "ex1:B1" |
| <http://example2.com/A>  | "ex2:A"  |
| <http://example2.com/B2> | "ex2:B2" |
| <http://example3.com/A>  | "ex3:A"  |
| <http://example3.com/B3> | "ex3:B3" |
| <http://example3.com/B4> | "ex3:B4" |
| <http://example4.com/A>  | ""       |
| <http://example4.com/B4> | ""       |
---------------------------------------
Share:
10,882
RN Hindarwan
Author by

RN Hindarwan

Updated on June 08, 2022

Comments

  • RN Hindarwan
    RN Hindarwan about 2 years

    I want to get all class that stored in sesame repository.

    This is my query

    SELECT ?class ?classLabel
    WHERE {
    ?class rdf:type rdfs:Class.
    ?class rdfs:label ?classLabel.
    }
    

    It's return all URI of class with label. For example,

    "http://example.com/A_Class" "A_Class"
    "http://example.com/B_Class" "B_Class"
    

    But, if namespace prefix already defined I want to get label with namespace defined. For example if I already defined namespace prefix "ex" for "http://example.com/", the result become

    "http://example.com/A_Class" "ex:A_Class"
    "http://example.com/B_Class" "ex:B_Class"