Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SPARQL query to get all class label with namespace prefix defined

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"
like image 408
RN Hindarwan Avatar asked Feb 15 '23 18:02

RN Hindarwan


2 Answers

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

like image 79
Steve Harris Avatar answered Mar 11 '23 09:03

Steve Harris


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> | ""       |
---------------------------------------
like image 22
Joshua Taylor Avatar answered Mar 11 '23 09:03

Joshua Taylor