我同意其他答案,即您正在尝试做一件奇怪的事情,至少正如问题中所述。将前缀与 相关联rdfs:label
并不是那么有用,因为生成的字符串可能代表也可能不代表类的实际 URI。假设你想要做的实际上是在给定一组前缀定义的情况下找出一个 URI 的前缀名称,你可以在 SPARQL 中做到这一点,而不需要很多嵌套IF
的 s;你可以通过使用 aVALUES
和 a来做到这一点FILTER
。
给定这样的数据,其中定义了许多类(我在这里没有定义任何标签,因为在这个例子中它们不是必需的),
@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 .
您可以编写这样的查询来选择所有类,检查它们的 URI 是否以多个定义的命名空间之一开头,如果是,则返回类和前缀形式:
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
结果产生:
$ 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> | "" |
---------------------------------------