SPARQL动态传参失效及IRI拼接函数技术咨询
SPARQL参数传递及IRI拼接问题解答
问题场景
刚接触SPARQL,在MarkLogic环境中实践时遇到两个问题:
- 通过map传递
sub参数的代码无结果返回,但硬编码IRI的代码可正常运行,原因是什么? - 已知
param1=http://dbpedia.org/resource/、param2=Porsche_912,SPARQL中是否有函数可将二者拼接为完整IRI?
无结果的代码
xquery version "1.0-ml"; import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy"; declare namespace s = "http://www.w3.org/2005/sparql-results#"; let $map := map:map() let $_ := map:put($map, "sub", "res:Porsche_912") let $result := sem:query-results-serialize( sem:sparql( "PREFIX pre: <http://dbpedia.org/ontology/Automobile/> PREFIX res: <http://dbpedia.org/resource/> SELECT ?p ?o WHERE { ?sub ?p ?o . }",$map ) ) return $result
可正常运行的代码
xquery version "1.0-ml"; import module namespace sem = "http://marklogic.com/semantics" at "/MarkLogic/semantics.xqy"; declare namespace s = "http://www.w3.org/2005/sparql-results#"; let $map := map:map() let $_ := map:put($map, "sub", "res:Porsche_912") let $result := sem:query-results-serialize( sem:sparql( "PREFIX pre: <http://dbpedia.org/ontology/Automobile/> PREFIX res: <http://dbpedia.org/resource/> SELECT ?p ?o WHERE { <http://dbpedia.org/resource/Porsche_912> ?p ?o . }",$map ) ) return $result
问题解答
1. 第一段代码无结果的原因
你传递给sub参数的是字符串"res:Porsche_912",SPARQL引擎会将其当作**字面量(字符串类型)**处理,而三元组中的主语是IRI类型的资源,字符串与IRI属于不同类型,自然匹配不到任何三元组。
硬编码的<http://dbpedia.org/resource/Porsche_912>是明确的IRI类型,能直接匹配三元组中的主语资源,所以可以正常返回结果。
修复第一段代码有两种方式:
- 方式一:在XQuery中构造IRI对象传递
将map中的值改为用sem:iri()构造的IRI:let $_ := map:put($map, "sub", sem:iri("http://dbpedia.org/resource/Porsche_912")) - 方式二:在SPARQL中把字符串转成IRI
修改SPARQL语句,用IRI()函数将参数字符串转为IRI(注意此时传递的sub参数需要是完整IRI字符串):PREFIX pre: <http://dbpedia.org/ontology/Automobile/> PREFIX res: <http://dbpedia.org/resource/> SELECT ?p ?o WHERE { BIND(IRI(?sub) AS ?subject) ?subject ?p ?o . }
2. SPARQL中拼接IRI的方法
SPARQL提供CONCAT()字符串拼接函数和IRI()类型转换函数,结合使用即可生成完整IRI:
方法一:直接拼接字符串转IRI
SELECT ?p ?o WHERE { BIND(CONCAT("http://dbpedia.org/resource/", "Porsche_912") AS ?fullIriStr) BIND(IRI(?fullIriStr) AS ?sub) ?sub ?p ?o . }
方法二:结合前缀变量拼接
如果param1是前缀对应的基础IRI,可通过str()函数提取前缀的字符串值再拼接:
PREFIX res: <http://dbpedia.org/resource/> SELECT ?p ?o WHERE { BIND(CONCAT(str(res:), "Porsche_912") AS ?fullIriStr) BIND(IRI(?fullIriStr) AS ?sub) ?sub ?p ?o . }
方法三:外部参数传入拼接
如果param1和param2是外部传入的变量,直接绑定后拼接:
SELECT ?p ?o WHERE { BIND(IRI(CONCAT(?param1, ?param2)) AS ?sub) ?sub ?p ?o . }
内容的提问来源于stack exchange,提问作者Pawan Saha
相关产品推荐
相关产品推荐

