Copyright © 2008-2026 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
RDF 是一种有向的、带标签的图数据模型,用于表示 Web 中的信息。本规范定义了用于 RDF 的 SPARQL 查询语言的语法和语义。SPARQL 可用于表达跨多种数据源的查询,无论数据是以 RDF 原生存储,还是通过中间件视为 RDF。SPARQL 具备查询必需和可选图模式及其合取与析取的能力。SPARQL 还支持聚合、子查询、否定、通过表达式创建值、可扩展的值测试,以及按源 RDF 图约束查询。SPARQL 查询 的结果可以是结果集,也可以是 RDF 图。
本节描述本文档在发布时的状态。当前 W3C 出版物列表以及本技术报告的最新修订版可在 W3C 标准与草案 索引中找到。
本规范由 RDF Star 工作组发布,作为 格式与勘误规范更新的一部分。
本文档由 RDF & SPARQL 工作组 作为工作草案发布,并使用 推荐标准 轨道。
作为 工作草案发布并不意味着获得 W3C 及其成员的认可。
这是一份草案文档,可能随时被其他文档更新、替换或废弃。 不应将本文档作为进行中的工作以外的内容引用。 对此即将推出的推荐标准的未来更新可能会纳入 新特性。
本文档由一个按照 W3C 专利 政策运作的工作组产出。 W3C 维护着一份 任何专利 披露的公开列表, 这些披露与该工作组的交付物有关;该页面还包含 披露专利的说明。任何实际知晓某项专利,并认为该专利包含 必要权利要求 的个人,必须依照 W3C 专利政策第 6 节披露相关信息。
本文档受 2025年8月18日 W3C 流程文档管辖。
RDF 是一种有向的、带标签的图数据模型,用于表示 Web 中的信息。RDF 常用于表示个人信息、社交网络、关于数字制品的元数据等,也用于提供一种在异构 信息源之间进行集成的手段。本规范定义了用于 RDF 的 SPARQL 查询语言的语法和语义。
用于 RDF 的 SPARQL 查询语言旨在满足 RDF 数据访问工作组在 [RDF-DAWG-UC]、 SPARQL 1.1 工作组在 [SPARQL-FEATURES] 以及 RDF-star 工作组 所确定的用例和需求。
除非节标题中另有说明,本文档中的所有章节和附录均为规范性内容。
本文档的本节,即 第 1 节,介绍 SPARQL 查询语言规范。它说明本规范文档的组织结构,以及整个规范中使用的约定。
本规范的 第 2 节 通过一系列示例查询和查询结果介绍 SPARQL 查询语言本身。 第 3 节 通过更多示例继续介绍 SPARQL 查询语言, 这些示例展示 SPARQL 表达对出现在查询结果中的 RDF 项进行约束的能力。
第 4 节 展示 SPARQL 查询语言语法的细节。它是该语言完整文法 的配套说明,并定义语法结构如何表示 IRI、空白节点、字面量和变量。第 4 节还定义若干 语法结构的含义,这些结构作为更冗长表达式的语法糖。
第 5 节 介绍基本图模式和组图模式,它们是构造更复杂 SPARQL 查询模式的构建块。第 6、7 和 8 节展示将 SPARQL 图模式组合成更大图模式的结构。 具体而言,第 6 节 介绍将查询的一部分设为可选的能力; 第 7 节 介绍表达替代图模式析取的能力;并且 第 8 节 介绍用于测试信息缺失的模式。
第 9 节 为图模式匹配添加属性路径, 既为查询提供紧凑表示,也提供在图中匹配任意长度路径的能力。
第 10 节 描述 SPARQL 中可能的赋值形式。
第 11 节 介绍对结果进行分组和聚合的机制, 这些机制可作为子查询纳入,如 第 12 节 所述。
第 13 节 介绍将查询部分约束到特定源图的能力。 第 13 节还展示 SPARQL 为查询定义源图的机制。
第 14 节 引用独立文档 SPARQL 1.1 联邦查询。
第 15 节 定义通过排序、切片、投影、限制以及 从解序列中移除重复项来影响查询解的结构。
第 16 节 定义四种 SPARQL 查询类型, 它们以不同形式生成结果。
第 17 节 定义 SPARQL 的可扩展值测试 和表达式框架。它展示可用于约束出现在查询结果中的值,以及计算 查询要返回的新值的函数和运算符。
第 18 节 是对 SPARQL 图模式和解修饰符求值的 形式化定义。
第 19 节 包含 SPARQL 查询和 SPARQL 1.1 更新 语言语法的 规范性定义,该定义以 EBNF 记法表示的文法给出。
在本文档中,除非另有说明,示例假定采用以下命名空间前缀定义:
| 前缀 | IRI |
|---|---|
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
rdfs: |
http://www.w3.org/2000/01/rdf-schema# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
fn: |
http://www.w3.org/2005/xpath-functions# |
本文档使用 RDF 1.1 Turtle [TURTLE] 数据 格式来显式显示每个三元组。Turtle 允许使用前缀缩写 IRI:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> :book1 dc:title "SPARQL Tutorial" .
结果集以表格形式说明。
| x | y | z |
|---|---|---|
| "Alice" | <http://example/a> |
“绑定”是一个二元组(变量,
RDF 项)。
在此结果集中,有三个变量:
x、y 和 z(显示为列标题)。每个解
在表格主体中显示为一行。 这里有一个解,其中变量 x
被绑定到 "Alice",变量 y 被绑定到
<http://example/a>,而变量 z 没有绑定到
RDF 项。变量在一个解中并不要求必须被绑定。
SPARQL 语言包含 IRI。 请注意,SPARQL 查询中的所有 IRI 都是绝对的;它们可以包含也可以不包含片段 标识符 [RFC3987] 第 3.1 节。IRI 包含 URI [RFC3986] 和 URL。 SPARQL 语法中的 缩写形式(相对 IRI 和前缀名)会被解析以生成绝对 IRI。
以下术语定义于 RDF 1.2 概念与抽象数据 模型 [RDF12-CONCEPTS],并在 SPARQL 中使用:
空白节点标识符是
SPARQL 和
RDF 具体序列化的一部分。
在本文档中,语法形式“_:abc”用于表示
空白节点标识符
为 abc 的情况,而“_:”是
Turtle 和 SPARQL 中用于引入带标识符的空白节点的语法。
大多数形式的 SPARQL 查询都包含一组三元组模式,称为基本图 模式。三元组模式类似于 RDF 三元组,但主语、谓语 和宾语中的每一个都可以是变量。当来自 RDF 数据子图的某个 RDF 项 可替换这些变量,并且所得结果与该子图 RDF 图等价时, 基本图模式就匹配该 RDF 数据的一个子图。
下面的示例展示一个 SPARQL 查询,用于从给定数据图中查找一本书的标题。
该查询由两部分组成:SELECT 子句标识要出现在查询结果中的
变量,而 WHERE 子句提供要与数据图匹配的
基本图模式。此示例中的基本图模式由一个三元组模式构成,该模式在
宾语位置有一个变量(?title)。
数据:
<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> "SPARQL Tutorial" .
查询:
SELECT ?title
WHERE
{
<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .
}
此查询在上述数据上有一个解:
查询结果:
| title |
|---|
| "SPARQL Tutorial" |
查询的结果是一个解序列, 对应于查询的图模式匹配数据的各种方式。一个查询可以有 零个、一个或多个解。
数据:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> . _:a foaf:name "Johnny Lee Outlaw" . _:a foaf:mbox <mailto:jlow@example.com> . _:b foaf:name "Peter Goodguy" . _:b foaf:mbox <mailto:peter@example.org> . _:c foaf:mbox <mailto:carol@example.org> .
查询:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE
{ ?x foaf:name ?name .
?x foaf:mbox ?mbox }
查询结果:
| name | mbox |
|---|---|
| "Johnny Lee Outlaw" | <mailto:jlow@example.com> |
| "Peter Goodguy" | <mailto:peter@example.org> |
每个解给出一种方式,在该方式中,被选择的变量可被绑定到 RDF 项, 从而使查询模式与数据匹配。结果集给出所有可能的解。在 上述示例中,数据的以下两个子集提供了两个匹配项。
_:a foaf:name "Johnny Lee Outlaw" .
_:a foaf:box <mailto:jlow@example.com> .
_:b foaf:name "Peter Goodguy" .
_:b foaf:box <mailto:peter@example.org> .
这是一个基本图模式匹配;查询模式中使用的所有变量 都必须在每个解中被绑定。
下面的数据包含三个 RDF 字面量:
PREFIX dt: <http://example.org/datatype#> PREFIX ns: <http://example.org/ns#> PREFIX : <http://example.org/ns#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> :x ns:p "cat"@en . :y ns:p "42"^^xsd:integer . :z ns:p "abc"^^dt:specialDatatype .
请注意,在 Turtle 中,"cat"@en 是一个 RDF 字面量,其词汇形式为“cat”,
语言标签为“en”;"42"^^xsd:integer 是一个带有
数据类型 http://www.w3.org/2001/XMLSchema#integer 的字面量;而
"abc"^^dt:specialDatatype 是一个带有数据类型
http://example.org/datatype#specialDatatype 的字面量。
该 RDF 数据是第 2.3.1–2.3.3 节中查询示例的数据图。
SPARQL 中的语言标签使用 @ 和语言标签表示,如
用于标识语言的标签
[BCP47] 中所定义。
以下查询没有解,因为 "cat" 与 "cat"@en 不是同一个 RDF
字面量:
SELECT ?v WHERE { ?v ?p "cat" }
| v |
|---|
但下面的查询会找到一个解,其中变量 v 绑定到
:x,因为指定了语言标签且其与给定数据匹配:
SELECT ?v WHERE { ?v ?p "cat"@en }
| v |
|---|
| <http://example.org/ns#x> |
SPARQL 还支持匹配给定的
基本方向。
与 Turtle 中一样,它写在语言标签之后,例如
@en--ltr。
基本方向被限制为 ltr 或 rtl。
与语言标签不同,它始终为小写。
SPARQL 查询中的整数表示数据类型为
xsd:integer 的 RDF 字面量。例如:42 是
"42"^^<http://www.w3.org/2001/XMLSchema#integer> 的缩写形式。
以下查询中的模式有一个解,其中变量 v 绑定到
:y。
SELECT ?v WHERE { ?v ?p 42 }
| v |
|---|
| <http://example.org/ns#y> |
第 4.1.2 节 定义了 SPARQL 中
xsd:float 和 xsd:double 的缩写形式。
以下查询有一个解,其中变量 v 绑定到
:z。查询处理器不必对该数据类型值空间中的值有任何理解。
因为词汇形式和数据类型 IRI 都匹配,所以该字面量匹配。
SELECT ?v WHERE { ?v ?p "abc"^^<http://example.org/datatype#specialDatatype> }
| v |
|---|
| <http://example.org/ns#z> |
查询结果可以包含空白节点。本文档的示例 结果集中,空白节点写作“_:”后跟一个 空白节点标识符的形式。
空白节点标识符的作用域限定于一个结果集(见“SPARQL 查询结果 XML 格式(第二
版)”和
“SPARQL 1.1 查询结果 JSON
格式”),或者,对于 CONSTRUCT 查询形式而言,限定于结果
图。在一个结果集中使用相同标识符表示同一个空白节点。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?x ?name
WHERE { ?x foaf:name ?name }
| x | name |
|---|---|
| _:c | "Alice" |
| _:d | "Bob" |
上述结果同样可以使用不同的空白节点 标识符给出,因为结果中的空白节点标识符只 表示解中的 RDF 项是否相同或 不同。
| x | name |
|---|---|
| _:r | "Alice" |
| _:s | "Bob" |
这两个结果包含相同信息:用于
匹配查询的空白节点在两个解中是不同的。结果集中的空白节点标识符
_:a 与
数据语法中使用的空白节点标识符之间不需要
存在任何关系。
应用程序编写者不应期望查询中的空白节点标识符 指向数据中的某个特定空白节点。
SPARQL 1.2 允许从复杂表达式创建值。下面的查询展示
CONCAT 函数如何用于连接 FOAF 数据中的名字和
姓氏,然后使用
SELECT 子句中的表达式来赋值,也可以使用
BIND 形式赋值。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:a foaf:givenName "John" .
_:a foaf:surname "Doe" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ( CONCAT(?G, " ", ?S) AS ?name )
WHERE { ?P foaf:givenName ?G ; foaf:surname ?S }
查询:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE {
?P foaf:givenName ?G ;
foaf:surname ?S
BIND(CONCAT(?G, " ", ?S) AS ?name)
}
| name |
|---|
| "John Doe" |
SPARQL 有若干查询形式。SELECT 查询
形式返回变量绑定。CONSTRUCT 查询形式返回 RDF 图。
该图基于一个模板构建,该模板用于根据查询图模式匹配的
结果生成 RDF 三元组。
数据:
PREFIX org: <http://example.com/ns#> _:a org:employeeName "Alice" . _:a org:employeeId 12345 . _:b org:employeeName "Bob" . _:b org:employeeId 67890 .
查询:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX org: <http://example.com/ns#>
CONSTRUCT { ?x foaf:name ?name }
WHERE { ?x org:employeeName ?name }
结果:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:x foaf:name "Alice" .
_:y foaf:name "Bob" .
它可以被序列化为 RDF/XML:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:foaf="http://xmlns.com/foaf/0.1/" >
<rdf:Description>
<foaf:name>Alice</foaf:name>
</rdf:Description>
<rdf:Description>
<foaf:name>Bob</foaf:name>
</rdf:Description>
</rdf:RDF>
图模式匹配会产生一个解序列,其中每个解都有一组
变量到 RDF 项的绑定。SPARQL FILTER 将解限制为
过滤表达式求值为 TRUE 的那些解。
本节提供对 SPARQL FILTER 的非正式介绍;它们的
语义定义在“表达式与值测试”一节中,
其中有一个完整的函数库。本节中的示例
共享一个输入图:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
SPARQL FILTER 函数,如 regex,可以
测试 RDF 字面量。regex 只匹配字符串
字面量。regex 可以通过使用 str 函数
来匹配其他字面量的词汇形式。
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
?x dc:title ?title
FILTER regex(?title, "^SPARQL")
}
查询结果:
| title |
|---|
| "SPARQL Tutorial" |
可使用“i”
标志使正则表达式匹配不区分大小写。
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
?x dc:title ?title
FILTER regex(?title, "web", "i" )
}
查询结果:
| title |
|---|
| "The Semantic Web" |
正则表达式语言由 XQuery 和 XPath 函数与运算符定义,并基于 XML Schema 正则表达式。
SPARQL FILTER 可以对算术表达式进行限制。
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title ?price
WHERE {
?x ns:price ?price .
FILTER (?price < 30.5)
?x dc:title ?title .
}
查询结果:
| title | price |
|---|---|
| "The Semantic Web" | 23 |
通过约束 price 变量,只有 :book2 匹配该查询,
因为只有 :book2 的价格小于 30.5,符合过滤
条件要求。
除 数值 类型外,SPARQL 还支持
xsd:string、xsd:boolean 和 xsd:dateTime
类型(见操作数数据类型)。运算符映射一节
描述运算符,函数定义一节描述
可应用于 RDF 项的函数。
本节涵盖 SPARQL 用于 RDF 项 和三元组模式的语法。 完整文法见第 19 节。
iri 产生式表示 IRI 集合 [RFC3987];IRI 是
URI [RFC3986] 的泛化,并且与
URI 和 URL 完全兼容。PrefixedName
产生式表示前缀名。前缀名到 IRI 的映射如下所述。IRI 引用(相对或
绝对 IRI)由 IRIREF 产生式表示,其中
“<”和“>”分隔符不构成 IRI 引用的一部分。相对 IRI 匹配
[RFC3987] 中第 2.2 节
“IRI 引用和 IRI 的 ABNF”里的 irelative-ref 引用,并按下文所述解析
为 IRI。
PREFIX 关键字将一个前缀标签与一个 IRI 关联。前缀名
是由冒号“:”分隔的前缀标签和局部部分。前缀
名通过将与前缀关联的 IRI 和局部部分连接起来映射为 IRI。
前缀标签或局部部分可以为空。
请注意,SPARQL 局部名允许以数字开头,而
XML 局部名不允许。
SPARQL 局部名还允许通过反斜杠
字符转义使用 IRI 中允许的非字母数字
字符(例如 ns:id\=123)。SPARQL 局部
名比
CURIE
有更多语法限制。
相对 IRI 按照 统一资源标识符(URI):通用 语法 [RFC3986] 与基 IRI 组合,只使用第 5.2 节中的基本算法。不执行基于语法的规范化或基于方案的 规范化(见 [RFC3986] 第 6.2.2 和 6.2.3 节)。 IRI 引用中额外允许的字符按未保留字符在 URI 引用中的处理方式处理, 如 国际化资源标识符 (IRI) [RFC3987] 第 6.5 节所述。
BASE 关键字定义用于根据
[RFC3986] 第
5.1.1 节“嵌入内容中的基 URI”解析相对 IRI 的基 IRI。第 5.1.2 节“来自
封装实体的基 URI”定义基 IRI 如何来自封装
文档,例如带有 xml:base 指令的 SOAP 信封,或带有 Content-Location 标头的 mime 多部分文档。
第 5.1.3 节“来自检索 URI 的基 URI”中标识的“检索 URI”,是获取特定 SPARQL
查询的 URL。如果
以上都未指定基 URI,则使用默认基 URI(第 5.1.4 节“默认
基 URI”)。
以下片段是写出同一 IRI 的几种不同方式:
<http://example.org/book/book1>
BASE <http://example.org/book/> <book1>
PREFIX book: <http://example.org/book/> book:book1
字面量的一般语法是一个字符串(用双引号
"..." 或单引号 '...' 括起),并带有可选的语言
标签(由 @ 引入),或可选的数据类型 IRI 或前缀名(由
^^ 引入)。
为方便起见,整数可以直接书写(不加引号,也不显式写出
数据类型 IRI),并解释为数据类型为
xsd:integer 的字面量;数字中有“.”但没有
指数的十进制数解释为 xsd:decimal;带指数的数字
解释为 xsd:double。xsd:boolean 类型的值也可以
写作 true 或 false。
为了便于书写本身包含引号或较长且包含换行符的 字面量值,SPARQL 提供了额外的引号结构,在 这种结构中字面量用三个单引号或双引号括起。
SPARQL 中的字面量语法示例包括:
"chat"'chat'@fr"xyz"^^<http://example.org/ns/userDatatype>"abc"^^appNS:appDataType'''The librarian said, "Perhaps you would enjoy 'War and
Peace'."'''1,等同于 "1"^^xsd:integer1.3,等同于 "1.3"^^xsd:decimal1.300,等同于 "1.300"^^xsd:decimal1.0e6,等同于 "1.0e6"^^xsd:doubletrue,等同于 "true"^^xsd:booleanfalse,等同于 "false"^^xsd:boolean匹配以下任一产生式的标记
INTEGER、
DECIMAL、
DOUBLE 或
BooleanLiteral 等同于一个字面量,
其词汇值为该标记,数据类型为相应的数据类型
(xsd:integer、xsd:decimal、
xsd:double 或 xsd:boolean)。
查询变量由“?”或“$”标记;“?”或“$”不是
变量名的一部分。在查询中,$abc 和 ?abc 标识同一个
变量。变量的可能名称在
SPARQL 文法中给出。
图模式中的
空白节点
充当变量,而不是对被查询数据中特定空白
节点的引用。空白节点由
标识符形式(例如“_:abc”)或
使用“[]”或“[...]”的缩写形式表示。
空白节点标识符写作“_:abc”,表示
标识符为“abc”的空白节点。同一个空白节点
标识符不能在同一查询中的两个不同基本图模式中使用。
只在查询语法中的一个位置使用的空白节点可以用
[] 表示。将使用一个唯一的空白节点来
形成三元组模式。
[:p :v] 结构可用于创建三元组
模式,其中唯一空白节点作为所含
谓词-对象对的主语。
以下两种形式
[ :p "v" ] .
[] :p "v" .
分配一个唯一空白节点(此处用
“_:b57”说明),并且二者等同于写作:
_:b57 :p "v" .
分配的空白节点可用作 进一步三元组模式的主语或宾语。例如,作为主语:
[ :p "v" ] :q "w" .
这等同于以下两个三元组:
_:b57 :p "v" . _:b57 :q "w" .
作为宾语时:
:x :q [ :p "v" ] .
这等同于以下两个三元组:
:x :q _:b57 . _:b57 :p "v" .
缩写空白节点语法可以与用于共同主语 和共同谓语的其他 缩写结合使用。
[ foaf:name ?name ; foaf:mbox <mailto:alice@example.org> ]
这等同于使用空白节点标识符来书写以下 基本图模式。
_:b18 foaf:name ?name . _:b18 foaf:mbox <mailto:alice@example.org> .
三元组模式写作主语、谓语和 宾语;某些常见三元组模式结构有缩写写法。
以下示例表达同一个查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE { <http://example.org/book/book1> dc:title ?title }
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
SELECT $title
WHERE { :book1 dc:title $title }
BASE <http://example.org/book/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT $title
WHERE { <book1> dc:title ?title }
具有共同主语的三元组模式可以这样书写:主语只写
一次,并通过使用“;”
记法用于多个三元组模式。
?x foaf:name ?name ; foaf:mbox ?mbox .
这等同于写出以下三元组模式:
?x foaf:name ?name . ?x foaf:mbox ?mbox .
如果三元组模式同时共享主语和谓语,则对象可以用
“,”分隔。
?x foaf:nick "Alice" , "Alice_" .
等同于写出以下三元组模式:
?x foaf:nick "Alice" . ?x foaf:nick "Alice_" .
对象列表可以与谓词-对象列表结合使用:
?x foaf:name ?name ; foaf:nick "Alice" , "Alice_" .
等价于:
?x foaf:name ?name . ?x foaf:nick "Alice" . ?x foaf:nick "Alice_" .
RDF 集合可以用语法“(element1 element2 ...)”写入三元组
模式中。形式“()”是 IRI
http://www.w3.org/1999/02/22-rdf-syntax-ns#nil
的另一种写法。
当与集合元素一起使用时,例如 (1 ?x 3 4),会为集合分配带
空白节点的三元组模式。集合头部的空白节点
可以在其他三元组模式中用作主语或宾语。由
集合语法分配的空白节点不会出现在查询中的其他地方。
(1 ?x 3 4) :p "w" .
是以下内容的语法糖(注意 b0、b1、b2
和 b3 不会出现在查询的任何其他地方):
_:b0 rdf:first 1 ;
rdf:rest _:b1 .
_:b1 rdf:first ?x ;
rdf:rest _:b2 .
_:b2 rdf:first 3 ;
rdf:rest _:b3 .
_:b3 rdf:first 4 ;
rdf:rest rdf:nil .
_:b0 :p "w" .
RDF 集合可以嵌套,并且可以涉及其他语法形式:
(1 [:p :q] ( 2 ) ) .
是以下内容的语法糖:
_:b0 rdf:first 1 ;
rdf:rest _:b1 .
_:b1 rdf:first _:b2 .
_:b2 :p :q .
_:b1 rdf:rest _:b3 .
_:b3 rdf:first _:b4 .
_:b4 rdf:first 2 ;
rdf:rest rdf:nil .
_:b3 rdf:rest rdf:nil .
关键字“a”可以在三元组模式中用作谓语,并且是 IRI
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
的另一种写法。
此关键字区分大小写。
?x a :Class1 . [ a :appClass ] :p "v" .
是以下内容的语法糖:
?x rdf:type :Class1 . _:b0 rdf:type :appClass . _:b0 :p "v" .
为应对 SPARQL 的语言演化,
可以使用 VERSION 指令。
当编写使用新特性的 SPARQL 查询时,例如
三元组项
或三元组项上的函数,
作者可以通过包含此
指令来声明使用新的语法形式,
后跟表示处理所包含特性所需版本的版本标签。
版本标签在下一节中定义。 处理器可以将无法识别的标签视为错误或警告。
VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?s ?date {
?s ?p ?o .
BIND( <<( ?s ?p ?o )>> AS ?tt )
:myreifier rdf:reifies ?tt .
:myreifier :tripleAdded ?date .
}
SPARQL 1.2 协议还提供了一个
版本声明,该声明使用
媒体类型的
version 参数。
如果没有 VERSION 指令,则会考虑这一点。
SPARQL 版本标签是一个字符串,用于 标识 SPARQL 查询的语法和语义一致性。
尽管 SPARQL 中的版本标签字符串与 RDF 定义的版本标签相同, 但它们的含义不同。具体而言,SPARQL 版本标签指的是 SPARQL 语法和语义,而 RDF 版本标签指的是 RDF 语法 和语义。
| 版本标签 | 语法 | 语义 |
|---|---|---|
| "1.2" | SPARQL 1.2 查询或更新语法 | SPARQL 1.2 查询 语言、SPARQL 1.2 更新 |
| "1.2-basic" | SPARQL 1.2 查询或更新语法,不含三元组项,也不含 主语或宾语位置上有三元组模式的三元组模式 | SPARQL 1.2 查询 语言、SPARQL 1.2 更新 |
| "1.1" | SPARQL 1.1 查询或更新语法,但允许使用版本指令 | SPARQL 1.1 查询 语言、SPARQL 1.1 更新 |
如果一个查询符合版本“1.1”,它也符合版本“1.2-basic”; 如果一个查询符合版本“1.2-basic”,它也符合版本“1.2”。
虽然“1.1”是可接受的版本标签,
但不鼓励在 VERSION 指令中使用它,
因为这会不必要地导致 SPARQL 1.1 解析器失败。
SPARQL 围绕图模式匹配构建。可以通过以各种方式 组合较小模式来形成更复杂的图模式:
在本节中,我们描述通过合取来组合模式的两种形式:基本图 模式,它组合三元组模式;以及组图模式,它组合所有其他 图模式。
查询中最外层的图模式称为查询模式。它在语法上
由 GroupGraphPattern 标识,如下所示
[17] |
WhereClause |
::= | 'WHERE'? GroupGraphPattern
|
基本图模式是三元组模式的集合。SPARQL 图模式匹配是根据 组合基本图模式匹配结果来定义的。
一组三元组模式序列,加上可选过滤器,构成一个基本图 模式。任何其他图模式都会终止一个基本图模式。
使用 _:abc 形式的空白节点时,空白节点的标识符
作用域限定于基本图模式。一个
空白节点标识符
在任何查询中只能用于一个基本图模式。
SPARQL 使用子图匹配对基本图模式求值,这一定义适用于 简单蕴涵。在满足下文所述的 某些条件时,SPARQL 可以扩展到其他形式的蕴涵。 文档 SPARQL 1.1 蕴涵制度 描述了若干具体的蕴涵制度。
在 SPARQL 查询字符串中,组图模式用花括号分隔:{}。
例如,此查询的查询模式是由一个基本图
模式组成的组图模式。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name .
?x foaf:mbox ?mbox .
}
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
{ ?x foaf:name ?name . }
{ ?x foaf:mbox ?mbox . }
}
组模式:
{ }
匹配任意图(包括空图),并产生一个不绑定任何 变量的解。例如:
SELECT ?x
WHERE {}
会匹配并产生一个解,其中变量 x 未绑定。
由关键字 FILTER 表达的约束,是对
该过滤器所在整个组中的解的限制。以下模式都有
相同的解:
{ ?x foaf:name ?name .
?x foaf:mbox ?mbox .
FILTER regex(?name, "Smith")
}
{ FILTER regex(?name, "Smith")
?x foaf:name ?name .
?x foaf:mbox ?mbox .
}
{ ?x foaf:name ?name .
FILTER regex(?name, "Smith")
?x foaf:mbox ?mbox .
}
{ ?x foaf:name ?name .
?x foaf:mbox ?mbox .
}
是由一个基本图模式组成的组,而该基本图模式由两个 三元组模式组成。
{
?x foaf:name ?name . FILTER regex(?name, "Smith")
?x foaf:mbox ?mbox .
}
是由一个基本图模式和一个过滤器组成的组,而该基本图模式 由两个三元组模式组成;过滤器不会将基本图模式拆分为两个 基本图模式。
{
?x foaf:name ?name .
{}
?x foaf:mbox ?mbox .
}
是由三个元素组成的组:一个由一个三元组模式组成的基本图模式、一个空 组,以及另一个由一个三元组模式组成的基本图模式。
基本图模式允许应用进行查询,其中整个查询模式必须 匹配才会有解。对于只包含组图 模式且至少有一个基本图模式的查询的每个解,每个变量都绑定到解中的一个 RDF 项。 然而,不能假定所有 RDF 图中都有规则、完整的结构。能够编写这样的查询很有用: 当信息可用时允许把信息加入解中,但不会因为查询模式的某一部分 不匹配而拒绝该解。可选匹配提供了这一功能:如果可选部分不匹配, 它不会创建绑定,但也不会消除该解。
图模式的可选部分可以在语法上通过将 OPTIONAL 关键字应用于图模式来指定:
pattern OPTIONAL { pattern }
语法形式:
{ OPTIONAL { pattern } }
等价于:
{ { } OPTIONAL { pattern } }
OPTIONAL 关键字是左结合的:
pattern OPTIONAL { pattern } OPTIONAL { pattern }
与以下形式相同:
{ pattern OPTIONAL { pattern } } OPTIONAL { pattern }
在可选匹配中,要么可选图模式匹配某个图,从而 为一个或多个解定义并添加绑定;要么它使解保持不变, 不添加任何额外绑定。
数据:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> _:a rdf:type foaf:Person . _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@example.com> . _:a foaf:mbox <mailto:alice@work.example> . _:b rdf:type foaf:Person . _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name .
OPTIONAL { ?x foaf:mbox ?mbox }
}
对于上述数据,查询结果为:
| name | mbox |
|---|---|
| "Alice" | <mailto:alice@example.com> |
| "Alice" | <mailto:alice@work.example> |
| "Bob" |
在名称为 "Bob" 的解中,没有 mbox 的值。
此查询查找数据中人员的姓名。如果存在一个谓词为
mbox 且主语相同的三元组,则解也会包含该三元组的宾语。
在此示例中,查询的可选匹配部分只给出一个三元组模式,
但一般而言,可选部分可以是任意图模式。整个可选
图模式必须匹配,才会影响查询解。
约束可以在可选图模式中给出。例如:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title ?price
WHERE {
?x dc:title ?title .
OPTIONAL { ?x ns:price ?price . FILTER (?price < 30) }
}
| title | price |
|---|---|
| "SPARQL Tutorial" | |
| "The Semantic Web" | 23 |
标题为“SPARQL Tutorial”的书没有出现价格,因为可选图
模式没有产生涉及变量“price”的解。
图模式是递归定义的。一个图模式可以有零个或多个可选 图模式,查询模式的任何部分也都可以有可选部分。在此示例中, 有两个可选图模式。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:homepage <http://work.example.org/alice/> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox ?hpage
WHERE {
?x foaf:name ?name .
OPTIONAL { ?x foaf:mbox ?mbox } .
OPTIONAL { ?x foaf:homepage ?hpage }
}
查询结果:
| name | mbox | hpage |
|---|---|---|
| "Alice" | <http://work.example.org/alice/> | |
| "Bob" | <mailto:bob@work.example> |
SPARQL 提供了一种组合图模式的手段,使得若干替代图 模式中的一个可以匹配。如果多个替代项匹配,则会找到所有可能的模式 解。
模式替代项在语法上用 UNION 关键字指定。
PREFIX dc10: <http://purl.org/dc/elements/1.0/> PREFIX dc11: <http://purl.org/dc/elements/1.1/> _:a dc10:title "SPARQL Query Language Tutorial" . _:a dc10:creator "Alice" . _:b dc11:title "SPARQL Protocol Tutorial" . _:b dc11:creator "Bob" . _:c dc10:title "SPARQL" . _:c dc11:title "SPARQL (updated)" .
PREFIX dc10: <http://purl.org/dc/elements/1.0/>
PREFIX dc11: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE { { ?book dc10:title ?title } UNION { ?book dc11:title ?title } }
查询结果:
| title |
|---|
| "SPARQL Protocol Tutorial" |
| "SPARQL" |
| "SPARQL (updated)" |
| "SPARQL Query Language Tutorial" |
此查询查找数据中书籍的标题,无论该标题是使用 Dublin Core 版本 1.0 还是版本 1.1 的属性记录的。若要准确确定信息是如何记录的,查询可以为 两个替代项使用不同变量:
PREFIX dc10: <http://purl.org/dc/elements/1.0/>
PREFIX dc11: <http://purl.org/dc/elements/1.1/>
SELECT ?x ?y
WHERE { { ?book dc10:title ?x } UNION { ?book dc11:title ?y } }
| x | y |
|---|---|
| "SPARQL (updated)" | |
| "SPARQL Protocol Tutorial" | |
| "SPARQL" | |
| "SPARQL Query Language Tutorial" |
这会返回这样的结果:来自 UNION 左分支的解中变量 x
被绑定,而来自右分支的解中变量 y 被绑定。
如果 UNION 模式的任何一部分都没有匹配,则图
模式不会匹配。
UNION 模式组合图模式;每种替代可能性都可以
包含多个三元组模式:
PREFIX dc10: <http://purl.org/dc/elements/1.0/>
PREFIX dc11: <http://purl.org/dc/elements/1.1/>
SELECT ?title ?author
WHERE {
{ ?book dc10:title ?title . ?book dc10:creator ?author }
UNION
{ ?book dc11:title ?title . ?book dc11:creator ?author }
}
| title | author |
|---|---|
| "SPARQL Query Language Tutorial" | "Alice" |
| "SPARQL Protocol Tutorial" | "Bob" |
此查询只有在一本书同时具有来自同一版本 Dublin Core 的标题谓词和创建者谓词时才会匹配该书。
SPARQL 查询语言包含两种否定方式:一种基于在被过滤的查询 解的上下文中,某个图模式是否匹配来过滤结果;另一种基于移除与另一个模式相关的解。
查询解的过滤在 FILTER 表达式中使用
NOT EXISTS 和 EXISTS 完成。请注意,过滤器作用域规则
适用于该过滤器所在的整个组。
NOT EXISTS 过滤表达式测试在过滤器所在组图模式中的变量值
给定时,某个图模式是否不匹配数据集。它不会生成任何额外绑定。
数据:
PREFIX : <http://example/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> :alice rdf:type foaf:Person . :alice foaf:name "Alice" . :bob rdf:type foaf:Person .
查询:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?person
WHERE
{
?person rdf:type foaf:Person .
FILTER NOT EXISTS { ?person foaf:name ?name }
}
查询结果:
| person |
|---|
| <http://example/bob> |
还提供了过滤表达式 EXISTS。它测试是否能在数据中找到该模式;
它不会生成任何额外绑定。
查询:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?person
WHERE {
?person rdf:type foaf:Person .
FILTER EXISTS { ?person foaf:name ?name }
}
查询结果:
| person |
|---|
| <http://example/alice> |
SPARQL 提供的另一种否定方式是 MINUS,它对两个
参数求值,然后计算左侧中与右侧解不兼容的解。
PREFIX : <http://example/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
:alice foaf:givenName "Alice" ;
foaf:familyName "Smith" .
:bob foaf:givenName "Bob" ;
foaf:familyName "Jones" .
:carol foaf:givenName "Carol" ;
foaf:familyName "Smith" .
PREFIX : <http://example/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?s
WHERE {
?s ?p ?o .
MINUS {
?s foaf:givenName "Bob" .
}
}
结果:
| s |
|---|
| <http://example/carol> |
| <http://example/alice> |
NOT EXISTS 和 MINUS 表示对
否定的两种理解方式:一种基于在已由查询模式确定的绑定
给定时测试某个模式是否存在于数据中,另一种基于两个模式的
求值来移除匹配项。在某些情况下,它们可能产生不同答案。
PREFIX : <http://example/> :a :b :c .
SELECT * {
?s ?p ?o
FILTER NOT EXISTS { ?x ?y ?z }
}
求值为一个没有解的结果集,因为 { ?x ?y ?z } 在任何给定
?s ?p ?o 的情况下都会匹配,所以 NOT EXISTS { ?x ?y ?z }
会消除所有解。
| s | p | o |
|---|
而使用 MINUS 时,第一部分
(?s ?p ?o)和第二部分(?x ?y ?z)之间没有共享变量,
因此不会消除任何绑定。
SELECT * {
?s ?p ?o
MINUS
{ ?x ?y ?z }
}
结果:
| s | p | o |
|---|---|---|
| <http://example/a> | <http://example/b> | <http://example/c> |
另一种情况是示例中存在一个具体模式(没有变量):
PREFIX : <http://example/>
SELECT * {
?s ?p ?o
FILTER NOT EXISTS { :a :b :c }
}
求值为一个没有查询解的结果集:
结果:| s | p | o |
|---|
而
PREFIX : <http://example/>
SELECT *
{
?s ?p ?o
MINUS { :a :b :c }
}
求值为包含一个查询解的结果集:
结果:
| s | p | o |
|---|---|---|
| <http://example/a> | <http://example/b> | <http://example/c> |
因为没有绑定匹配,所以没有解被消除。
也会出现差异,因为在过滤器中,来自组的变量
处于作用域内。
在此示例中,NOT EXISTS 内部的 FILTER
可以访问当前考虑的解中 ?n 的值。
PREFIX : <http://example.com/> :a :p 1 . :a :q 1 . :a :q 2 . :b :p 3.0 . :b :q 4.0 . :b :q 5.0 .
使用 FILTER NOT EXISTS 时,测试针对
?x :p ?n 的每个可能解进行:
PREFIX : <http://example.com/>
SELECT * WHERE {
?x :p ?n
FILTER NOT EXISTS {
?x :q ?m .
FILTER(?n = ?m)
}
}
| x | n |
|---|---|
| <http://example.com/b> | 3.0 |
而使用 MINUS 时,模式内部的 FILTER 没有
?n 的值,因此它始终未绑定:
PREFIX : <http://example/>
SELECT * WHERE {
?x :p ?n
MINUS {
?x :q ?m .
FILTER(?n = ?m)
}
}
| x | n |
|---|---|
| <http://example.com/b> | 3.0 |
| <http://example.com/a> | 1 |
属性路径是图中两个图节点之间可能的路径。一个平凡情况 是长度恰好为 1 的属性路径,即一个三元组模式。路径的两端可以是 RDF 项或变量。变量不能用作路径本身的一部分,只能用于 两端。
属性路径允许对某些 SPARQL 基本图模式使用更简洁的表达, 并且还增加了通过任意长度 路径匹配两个资源连通性的能力。
在下面的描述中,iri 要么是完整写出的 IRI
或用前缀名缩写的 IRI,要么是关键字 a。
elt
是一个路径元素,它本身可以由路径结构组成。
| 语法形式 | 属性路径表达式名称 | 匹配项 |
|---|---|---|
iri |
PredicatePath | 一个 IRI。长度为一的路径。 |
^elt |
InversePath | 反向路径(从宾语到主语)。 |
elt1 / elt2 |
SequencePath | 由 elt1 后跟 elt2 的序列路径。 |
elt1 | elt2 |
AlternativePath | elt1 或 elt2 的替代路径(会尝试所有
可能性)。 |
elt* |
ZeroOrMorePath | 通过零次或多次匹配
elt 来连接路径主语和宾语的路径。
|
elt+ |
OneOrMorePath | 通过一次或多次匹配
elt 来连接路径主语和宾语的路径。
|
elt? |
ZeroOrOnePath | 通过零次或一次匹配
elt 来连接路径主语和宾语的路径。
|
!iri or !(iri1|
...|irin) |
NegatedPropertySet | 否定属性集。不是 irii 之一的 IRI。
!iri 是 !(iri) 的缩写。
|
!^iri or !(^iri1|
...|^irin) |
NegatedPropertySet | 否定属性集,其中被排除的匹配基于反向路径。 也就是说,不是作为反向路径的 iri1...irin 之一。 !^iri 是 !(^iri) 的缩写。
|
!(iri1| ...|irij|^irij+1|
...|^irin) |
NegatedPropertySet | 否定属性集中正向属性与反向属性的组合。 |
(elt) |
组路径 elt,括号控制优先级。 |
否定属性集中 IRI 和反向 IRI 的顺序并不重要,它们 可以以混合顺序出现。
语法形式的优先级从高到低如下:
*、? 和 +/|组内优先级从左到右。
替代项:匹配一种或两种可能性
{ :book1 dc:title|rdfs:label ?displayString }
也可以写作:
{
:book1 <http://purl.org/dc/elements/1.1/title> | <http://www.w3.org/2000/01/rdf-schema#label> ?displayString
}
序列:查找 Alice 认识的任何人的姓名。
{
?x foaf:mbox <mailto:alice@example> .
?x foaf:knows/foaf:name ?name .
}
序列:查找距离 2 条“foaf:knows”链接的人的姓名。
{
?x foaf:mbox <mailto:alice@example> .
?x foaf:knows/foaf:knows/foaf:name ?name .
}
这与以下 SPARQL 查询相同:
SELECT ?x ?name {
?x foaf:mbox <mailto:alice@example> .
?x foaf:knows [ foaf:knows [ foaf:name ?name ]].
}
或者,使用显式变量:
SELECT ?x ?name {
?x foaf:mbox <mailto:alice@example> .
?x foaf:knows ?a1 .
?a1 foaf:knows ?a2 .
?a2 foaf:name ?name .
}
过滤重复项:因为 Alice 认识的人很可能认识 Alice,所以上面的示例 可能包含 Alice 本人。可使用以下方式避免这种情况:
{ ?x foaf:mbox <mailto:alice@example> .
?x foaf:knows/foaf:knows ?y .
FILTER ( ?x != ?y )
?y foaf:name ?name
}
反向属性路径:这两个是同一个查询;第二个只是反转 属性方向,从而交换主语和宾语的角色。
{ ?x foaf:mbox <mailto:alice@example> }
{ <mailto:alice@example> ^foaf:mbox ?x }
反向路径序列:查找所有认识 ?x 所认识的某人的人。
{
?x foaf:knows/^foaf:knows ?y .
FILTER(?x != ?y)
}
这等价于(?gen1 是系统生成的变量):
{
?x foaf:knows ?gen1 .
?y foaf:knows ?gen1 .
FILTER(?x != ?y)
}
任意长度匹配:查找所有可从 Alice 通过
foaf:knows 到达的人的姓名:
{
?x foaf:mbox <mailto:alice@example> .
?x foaf:knows+/foaf:name ?name .
}
任意长度路径中的替代项:
{ ?ancestor (ex:motherOf|ex:fatherOf)+ <#me> }
任意长度路径匹配:某些形式的有限推理也是可能的。 例如,对于 RDFS,资源的所有类型和超类型:
{ <http://example/thing> rdf:type/rdfs:subClassOf* ?type }
所有资源及其所有推断类型:
{ ?x rdf:type/rdfs:subClassOf* ?type }
子属性:
{ ?x ?p ?v . ?p rdfs:subPropertyOf* :property }
否定属性路径:查找已连接但不是通过 rdf:type 连接的节点(任一方向):
{ ?x !(rdf:type|^rdf:type) ?y }
RDF 集合中的元素:
{ :list rdf:rest*/rdf:first ?element }
注:此路径表达式不保证结果的顺序。
SPARQL 属性路径将 RDF 三元组视为一个有向的、可能有环的、带 命名边的图。属性路径表达式的求值可能导致重复项,因为 等价模式中引入的任何变量都不是结果的一部分,也未在其他地方 使用。它们会被结果隐式投影到仅查询中给出的变量而隐藏。
例如,基于以下数据:
PREFIX : <http://example/> :order :item :z1 . :order :item :z2 . :z1 :name "Small" . :z1 :price 5 . :z2 :name "Large" . :z2 :price 5 .
查询:
PREFIX : <http://example/>
SELECT *
{ ?s :item/:price ?x . }
结果:
| s | x |
|---|---|
| <http://example/order> | 5 |
| <http://example/order> | 5 |
而如果将查询写出以包含中间变量
(?_a),结果中就没有重复行:
PREFIX : <http://example/>
SELECT *
{ ?s :item ?_a .
?_a :price ?x .
}
结果:
| s | _a | x |
|---|---|---|
| <http://example/order> | <http://example/z1> | 5 |
| <http://example/order> | <http://example/z2> | 5 |
当查询还涉及聚合操作时,与图模式的等价性尤其重要。 可以用以下方式求得订单的总成本
PREFIX : <http://example/>
SELECT (sum(?x) AS ?total) {
:order :item/:price ?x
}
| total |
|---|
| 10 |
可以使用“零次或多次”属性路径运算符 * 和“一次或多次”
属性路径运算符 +,找到主语和宾语之间通过任意长度属性路径形成的
连通性。还有一个“零次或一次”连通性属性
路径运算符 ?。
这些运算符都会使用属性路径表达式,按该运算符所限制的次数 尝试使用路径步骤在主语和宾语之间找到连接。
例如,可以用以下方式找到资源的所有可能类型,包括资源的超类型:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?x ?type
{
?x rdf:type/rdfs:subClassOf* ?type
}
类似地,查找所有通过
foaf:knows 关系与 :x 相连的人,
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX : <http://example/>
SELECT ?person
{
:x foaf:knows+ ?person
}
这种连通性匹配不会引入重复项(它不会包含 该连接可形成方式数量的任何计数),即使重复路径本身 原本会导致重复项。
被匹配的图可以包含环。连通性匹配的定义保证 匹配环不会导致未定义或无限结果。
表达式的值可以通过把一个新变量绑定到 该表达式的值而加入解映射,该值是一个 RDF 项。随后该变量可以在查询中使用, 也可以在结果中返回。
有三种语法形式允许这样做:BIND 关键字、
SELECT 子句中的表达式和
GROUP BY 子句中的表达式。赋值形式为
(expression AS ?var)。
如果表达式求值产生错误,则该变量在该 解中保持未绑定,但查询求值继续。
也可以使用
VALUES 将数据作为内联数据直接包含在查询中。
BIND 形式允许从基本图
模式或属性路径表达式将一个值赋给变量。使用 BIND 会结束前面的基本图
模式。由 BIND 子句引入的变量,在使用 BIND 的位置之前,
不得已在该组图模式中使用过。
示例:
数据:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book1 ns:discount 0.2 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 . :book2 ns:discount 0.25 .
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title ?price
{
?x ns:price ?p .
?x ns:discount ?discount
BIND (?p*(1-?discount) AS ?price)
FILTER(?price < 20)
?x dc:title ?title .
}
等价查询(BIND 结束基本图模式;
FILTER 应用于整个组图模式):
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title ?price
{ { ?x ns:price ?p .
?x ns:discount ?discount
BIND (?p*(1-?discount) AS ?price)
}
{?x dc:title ?title . }
FILTER(?price < 20)
}
结果:
| title | price |
|---|---|
| "The Semantic Web" | 17.25 |
数据可以直接写在图模式中,也可以使用
VALUES 加入查询。VALUES 以
解序列的形式提供内联数据,该解序列通过
联接操作与查询求值结果组合。应用可使用它
对查询结果提供具体要求;提供通过
SERVICE 关键字进行联邦查询的 SPARQL 查询引擎
实现,也可以使用它向远程查询服务发送约束更强的查询。
VALUES 允许在数据块中指定多个变量;对于只指定一个变量和若干
值的常见情形,有一种特殊语法。
在以下示例中,有一个包含两个变量 ?x 和
?y 的表。第二行没有 ?y 的值。
VALUES (?x ?y) {
(:uri1 1)
(:uri2 UNDEF)
}
可选地,当只有一个变量和若干值时:
VALUES ?z { "abc" "def" }
这与使用一般形式相同:
VALUES (?z) { ("abc") ("def") }
请注意,同一变量不能在 VALUES 子句的变量列表中被提及多次。
VALUES 数据块可以出现在查询模式中,也可以出现在
SELECT 查询的末尾,包括子查询。
数据:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 .
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?title ?price
{
VALUES ?book { :book1 :book3 }
?book dc:title ?title ;
ns:price ?price .
}
结果:
| book | title | price |
|---|---|---|
| <http://example.org/book/book1> | "SPARQL Tutorial" | 42 |
如果某个变量在 VALUES 子句中的特定解没有值,
则使用关键字 UNDEF 代替 RDF 项。
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?title ?price
{
?book dc:title ?title ;
ns:price ?price .
VALUES (?book ?title) {
(UNDEF "SPARQL Tutorial")
(:book2 UNDEF)
}
}
| book | title | price |
|---|---|---|
| <http://example.org/book/book1> | "SPARQL Tutorial" | 42 |
| <http://example.org/book/book2> | "The Semantic Web" | 23 |
在此示例中,VALUES 也可以指定为在
SELECT 查询的结果上执行:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX : <http://example.org/book/>
PREFIX ns: <http://example.org/ns#>
SELECT ?book ?title ?price {
?book dc:title ?title ;
ns:price ?price .
}
VALUES (?book ?title) {
(UNDEF "SPARQL Tutorial")
(:book2 UNDEF)
}
这是一个不同的查询,但在该示例情境下具有相同结果。
聚合会把表达式应用于解的分组。默认情况下,一个解集由 一个包含所有解的单一分组组成。
可以使用 GROUP BY 语法指定分组。
SPARQL 1.1 版本中定义的聚合包括 COUNT、SUM、
MIN、MAX、AVG、GROUP_CONCAT 和
SAMPLE。
当查询者希望看到基于一组解计算出的结果,而不是单个解时, 会使用聚合。例如查看某个特定 变量所取的最大值,而不是分别查看每个值。
数据:
PREFIX : <http://books.example/> :org1 :affiliates :auth1, :auth2 . :auth1 :writesBook :book1, :book2 . :book1 :price 9 . :book2 :price 5 . :auth2 :writesBook :book3 . :book3 :price 7 . :org2 :affiliates :auth3 . :auth3 :writesBook :book4 . :book4 :price 7 .
查询:
PREFIX : <http://books.example/>
SELECT (SUM(?lprice) AS ?totalPrice)
WHERE {
?org :affiliates ?auth .
?auth :writesBook ?book .
?book :price ?lprice .
}
GROUP BY ?org
HAVING (SUM(?lprice) > 10)
结果:
| totalPrice |
|---|
| 21 |
此示例展示聚合的两个特性:GROUP BY,它按照
一个或多个表达式(在此例中为 ?org)对查询解进行分组;以及
HAVING,它类似于 FILTER 表达式,但作用于
分组,而不是单个解。
该示例通过按照 GROUP BY
表达式对解分组而产生(即所有 ?org 取某一特定值的解都位于
同一分组内),并在该分组上求值集函数 SUM。随后
用 HAVING 表达式过滤分组,该表达式移除所有
SUM(?lprice) 不大于 10 的分组。
在聚合查询和子查询中,出现在查询模式中但不在
GROUP BY 子句中的变量,只有在被聚合时,才可以被投影或用于 select 表达式。
SAMPLE 聚合可用于此目的。详情见关于
投影限制的章节。
应注意,按照函数的规则,聚合
表达式必须具有别名(同样类似于 BIND 子句,使用
关键字 AS),才能从查询或子查询中投影出来。在
上面的示例中,这是使用变量 ?totalPrice 完成的。如果
聚合投影变量使用的名称已在其他聚合投影中或
WHERE 子句中使用,则是错误。
为了计算某个解的聚合值,首先将解划分为 一个或多个分组,然后为每个分组计算聚合值。
如果在查询层级中的 SELECT、HAVING 或
ORDER BY 中使用了聚合,但未使用 GROUP BY 项,
则这会被视为一个包含所有解的单一隐式分组。
在 GROUP BY 子句中可以使用绑定关键字 AS,
例如 GROUP BY (?x + ?y AS ?z)。这等价于
{ ... BIND (?x + ?y AS ?z) } GROUP BY ?z。
例如,给定一个解序列 S:
( {?x→2, ?y→3}, {?x→2, ?y→5}, {?x→6, ?y→7} ),我们
可能希望按照 ?x 的值对解分组,并计算每个分组中
?y 值的平均值。
这可以写作:
SELECT (AVG(?y) AS ?avg)
WHERE {
?a :x ?x ;
:y ?y .
}
GROUP BY ?x
HAVING 作用于已分组的解集,其方式与
FILTER 作用于未分组的解集相同。
HAVING 表达式具有与分组查询投影相同的求值规则,
如下一节所述。
下面给出一个使用 HAVING 的示例。
PREFIX : <http://data.example/>
SELECT (AVG(?size) AS ?asize)
WHERE {
?x :size ?size
}
GROUP BY ?x
HAVING(AVG(?size) > 10)
这将返回按主语分组的平均 size,但只返回平均 size 大于 10 的分组。
在使用分组的查询层级中(无论是显式使用 GROUP BY 子句,
还是在投影、HAVING 或 ORDER BY 子句中使用聚合),
出现在该查询层级的投影或 SELECT 表达式中的每一次变量出现
必须满足以下条件之一:
GROUP BY 变量出现(其
对应的 GROUP BY 表达式只由变量 V 组成,或
具有 (expr AS V) 形式)MIN(?v) 或
AVG(?v+2))
如果这样的变量出现不满足这些条件之一,则该查询在语法上 无效。
例如,以下查询是合法的,因为 ?x 被给定为 GROUP BY
项。
PREFIX : <http://example.com/data/#>
SELECT ?x (MIN(?y) * 2 AS ?min)
WHERE {
?x :p ?y .
?x :q ?z .
} GROUP BY ?x (STR(?z))
请注意,投影 STR(?z) 是不合法的,因为该表达式既不是简单
变量,
也不是具名 GROUP BY 表达式。不过,如果使用
GROUP BY ?x (STR(?z) AS ?strZ),
就可以投影 ?strZ。
其他使用不满足上述条件的变量的表达式,可以使用
SAMPLE 聚合从其分组中投影出来。
本节展示一个使用聚合的示例查询,说明在存在聚合时 如何处理结果中的错误。
数据:
PREFIX : <http://example.com/data/#> :x :p 1, 2, 3, 4 . :y :p 1, _:b2, 3, 4 . :z :p 1.0, 2.0, 3.0, 4 .
查询:
PREFIX : <http://example.com/data/#>
SELECT ?g (AVG(?p) AS ?avg) ((MIN(?p) + MAX(?p)) / 2 AS ?c)
WHERE {
?g :p ?p .
}
GROUP BY ?g
结果:
| g | avg | c |
|---|---|---|
| <http://example.com/data/#x> | 2.5 | 2.5 |
| <http://example.com/data/#y> | ||
| <http://example.com/data/#z> | 2.5 | 2.5 |
请注意,:y 分组的绑定未包含在结果中,因为 Avg({1, _:b2, 3, 4}) 和 (_:b2 + 4) / 2 的求值是错误,从而从 解中移除了这些绑定。
子查询是一种把 SPARQL 查询嵌入其他查询中的方式,通常用于实现 否则无法实现的结果,例如限制查询中某个 子表达式的结果数量。
由于 SPARQL 查询求值具有自底向上的性质,子查询会在逻辑上 首先求值,然后将结果投影到外层查询。
请注意,只有从子查询中投影出的变量才对外层查询可见,或 处于作用域内。
数据:
PREFIX : <http://people.example/> :alice :name "Alice", "Alice Foo", "A. Foo" . :alice :knows :bob, :carol . :bob :name "Bob", "Bob Bar", "B. Bar" . :carol :name "Carol", "Carol Baz", "C. Baz" .
为所有认识 Alice 且具有姓名的人返回一个姓名(排序顺序最低的那个)。
查询:
PREFIX : <http://people.example/>
PREFIX : <http://people.example/>
SELECT ?y ?minName
WHERE {
:alice :knows ?y .
{
SELECT ?y (MIN(?name) AS ?minName)
WHERE {
?y :name ?name .
} GROUP BY ?y
}
}
结果:
| y | minName |
|---|---|
| :bob | "B. Bar" |
| :carol | "C. Baz" |
此结果通过首先求值内层查询而得到:
SELECT ?y (MIN(?name) AS ?minName)
WHERE {
?y :name ?name .
} GROUP BY ?y
这会产生以下解序列:
| y | minName |
|---|---|
| :alice | "A. Foo" |
| :bob | "B. Bar" |
| :carol | "C. Baz" |
它与外层查询的结果进行联接:
| y |
|---|
| :bob |
| :carol |
RDF 数据模型将信息表达为由主语、 谓语和宾语三元组组成的图。许多 RDF 数据存储保存多个 RDF 图,并记录 关于每个图的信息,从而允许应用进行涉及来自多个 图的信息的查询。
SPARQL 查询针对一个 RDF 数据集 [RDF12-CONCEPTS] 执行,该数据集表示一个 图的集合。RDF 数据集包含一个没有名称的图,即默认图,以及 零个或多个命名图,其中每个命名图由 IRI 或空白节点标识。SPARQL 查询 可以 将查询模式的不同部分与不同图匹配,如 13.3 查询数据集一节所述。
RDF 数据集可以包含零个命名图;RDF 数据集始终包含一个默认 图。查询不需要涉及匹配默认图;查询也可以只涉及 匹配命名图。
用于匹配基本图模式的图称为活动图。在
前面的章节中,所有查询都展示为针对单个图执行,即以 RDF 数据集的默认
图作为活动图。GRAPH 关键字用于在查询的一部分中使
活动图成为数据集中所有命名图之一。
RDF 数据集的定义 [RDF12-CONCEPTS] 并不限制命名图和默认 图之间的关系。信息可以在不同图中重复;图之间的关系也可以被 暴露出来。两种有用的安排是:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
<http://example.org/bob> dc:publisher "Bob" .
<http://example.org/alice> dc:publisher "Alice" .
GRAPH <http://example.org/bob> {
_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
}
GRAPH <http://example.org/alice> {
_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .
}
在此示例中,默认图包含两个命名 图的发布者名称。在此 示例中,命名图中的三元组在默认图中不可见。
示例 2:
RDF 数据可以通过 图的 RDF 合并 [RDF12-SEMANTICS] 来组合。RDF 数据集中一种可能的图安排 是让默认图成为命名图中部分或全部信息的 RDF 合并。
在下一个示例中,命名图包含与之前相同的三元组。RDF 数据集 在默认图中包含这些命名图的 RDF 合并, 并保持空白节点彼此不同。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:x foaf:name "Bob" .
_:x foaf:mbox <mailto:bob@oldcorp.example.org> .
_:y foaf:name "Alice" .
_:y foaf:mbox <mailto:alice@work.example.org> .
GRAPH <http://example.org/bob> {
_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
}
GRAPH <http://example.org/alice> {
_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .
}
在 RDF 合并中,合并图中的空白节点不会与 被合并图中的空白节点共享。
SPARQL 查询可以通过使用
FROM 子句和 FROM NAMED 子句来描述 RDF 数据集,从而指定用于匹配的数据集。
如果查询提供了这样的数据集描述,则会用它替代查询服务在未提供数据集描述时
会使用的任何数据集。RDF 数据集也可以在
SPARQL 协议
请求中指定,在
这种情况下,协议描述会覆盖查询本身中的任何描述。如果数据集描述
对服务不可接受,查询服务可以拒绝查询请求。
FROM 和 FROM NAMED 关键字允许查询通过引用指定 RDF
数据集;它们表示该数据集应包含从给定 IRI(即给定 IRI 引用的绝对形式)
所标识资源的表示中获得的图。由若干 FROM 和
FROM NAMED 子句产生的数据集是:
FROM 子句所引用图的 RDF 合并组成;以及
FROM NAMED 子句提供一个。如果没有 FROM 子句,但有一个或多个 FROM NAMED
子句,则该数据集包含一个空图作为默认图。
每个 FROM 子句包含一个 IRI,表示用于形成
默认图的图。这不会把该图作为命名图加入。
在此示例中,RDF 数据集包含一个默认图且没有命名 图:
# Default graph (located at http://example.org/foaf/aliceFoaf) PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
FROM <http://example.org/foaf/aliceFoaf>
WHERE { ?x foaf:name ?name }
| name |
|---|
| "Alice" |
如果查询提供多个 FROM 子句,即提供多个 IRI
来表示默认图,则默认图是
从给定 IRI 所标识资源的表示中取得的图的
RDF 合并。
查询可以使用 FROM
NAMED 子句为 RDF 数据集中的命名图提供 IRI。每个 IRI 用于在 RDF 数据集中提供一个命名图。
在两个或更多 FROM NAMED 子句中使用
同一 IRI,会导致数据集中出现一个具有该 IRI 的命名图。
# Graph: http://example.org/bob PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Bob" . _:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graph: http://example.org/alice PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> .
... FROM NAMED <http://example.org/alice> FROM NAMED <http://example.org/bob> ...
FROM NAMED 语法暗示 IRI 标识相应的
图,但 RDF 数据集中 IRI 与图之间的关系是间接的。IRI
标识一个资源,而该资源由一个图表示(或者更准确地说:
由一个序列化图的文档表示)。更多
详细信息
见 [WEBARCH]。
FROM 子句和 FROM NAMED 子句可以在同一
查询中使用。
# Default graph (located at http://example.org/dft.ttl) PREFIX dc: <http://purl.org/dc/elements/1.1/> <http://example.org/bob> dc:publisher "Bob Hacker" . <http://example.org/alice> dc:publisher "Alice Hacker" .
# Named graph: http://example.org/bob PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Bob" . _:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Named graph: http://example.org/alice PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example.org> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?who ?g ?mbox
FROM <http://example.org/dft.ttl>
FROM NAMED <http://example.org/alice>
FROM NAMED <http://example.org/bob>
WHERE
{
?g dc:publisher ?who .
GRAPH ?g { ?x foaf:mbox ?mbox }
}
此查询的 RDF 数据集包含一个默认图和两个命名图。
GRAPH 关键字在下文描述。
构造数据集所需的动作不能仅由数据集
描述确定。如果某个 IRI 在数据集描述中出现两次,无论是使用两个
FROM 子句,还是一个 FROM 子句和一个
FROM NAMED
子句,都不意味着会恰好进行一次或恰好两次尝试来获取
与该 IRI 关联的 RDF 图。因此,不能对从数据集描述中这两次出现获得的三元组中的空白
节点身份作出假设。一般而言,也不能对这些图的等价性作出假设。
查询一组图时,使用 GRAPH 关键字将
模式与命名图匹配。GRAPH 可以提供一个 IRI 来选择一个图,
也可以使用一个变量,该变量会遍历查询的 RDF
数据集中所有命名图的 IRI。
使用 GRAPH 会改变查询中该部分内
图模式匹配所用的活动图。在 GRAPH 使用范围之外,
使用默认图进行匹配。
以下两个图将用于示例:
# Named graph: http://example.org/foaf/aliceFoaf PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> . _:a foaf:knows _:b . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@work.example> . _:b foaf:nick "Bobby" . _:b rdfs:seeAlso <http://example.org/foaf/bobFoaf> . <http://example.org/foaf/bobFoaf> rdf:type foaf:PersonalProfileDocument .
# Named graph: http://example.org/foaf/bobFoaf
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
_:z foaf:mbox <mailto:bob@work.example> .
_:z rdfs:seeAlso <http://example.org/foaf/bobFoaf> .
_:z foaf:nick "Robert" .
<http://example.org/foaf/bobFoaf>
rdf:type foaf:PersonalProfileDocument .
下面的查询将图模式与数据集中的每个命名图匹配,
并形成这样的解:src 变量绑定到
正在匹配的图的 IRI。图模式在活动图分别为数据集中各
命名图的情况下进行匹配。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?src ?bobNick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
{
GRAPH ?src
{ ?x foaf:mbox <mailto:bob@work.example> .
?x foaf:nick ?bobNick
}
}
查询结果给出找到该信息的图名称以及 Bob 昵称的 值:
| src | bobNick |
|---|---|
| <http://example.org/foaf/aliceFoaf> | "Bobby" |
| <http://example.org/foaf/bobFoaf> | "Robert" |
查询可以通过提供图 IRI,把所应用的匹配限制到特定图。
这会将活动图设置为由该 IRI 命名的图。此查询查找
图 http://example.org/foaf/bobFoaf 中给出的 Bob
昵称。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX data: <http://example.org/foaf/>
SELECT ?nick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
{
GRAPH data:bobFoaf {
?x foaf:mbox <mailto:bob@work.example> .
?x foaf:nick ?nick
}
}
它产生一个解:
| nick |
|---|
| "Robert" |
在 GRAPH 子句中使用的变量,也可以用于另一个
GRAPH 子句,或用于与数据集中的默认图匹配的图模式。
下面的查询使用 IRI 为 http://example.org/foaf/aliceFoaf
的图来查找 Bob 的资料文档;随后它将另一个模式与该图匹配。
第二个 GRAPH 子句中的模式会找到
与第一个 GRAPH 子句中找到的邮箱(变量 mbox)
相同的人员的空白节点(变量 w),这是因为
从 Alice 的 FOAF 文件匹配变量 whom 时使用的
空白节点,与资料文档中的空白节点并不相同(它们位于不同图中)。
PREFIX data: <http://example.org/foaf/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?mbox ?nick ?ppd
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE {
GRAPH data:aliceFoaf {
?alice foaf:mbox <mailto:alice@work.example> ;
foaf:knows ?whom .
?whom foaf:mbox ?mbox ;
rdfs:seeAlso ?ppd .
?ppd a foaf:PersonalProfileDocument .
}
GRAPH ?ppd {
?w foaf:mbox ?mbox ;
foaf:nick ?nick
}
}
| mbox | nick | ppd |
|---|---|---|
| <mailto:bob@work.example> | "Robert" | <http://example.org/foaf/bobFoaf> |
Alice 的 FOAF 文件中给出 Bob 的 nick 的任何三元组,都不会用于为
Bob 提供 nick,因为涉及变量 nick 的模式被
ppd 限制到特定的个人资料文档。
查询模式可以同时涉及默认图和命名图。在此示例中, 一个聚合器在两个不同时间读取了一个 Web 资源。每次将图读入 聚合器时,本地系统都会为其赋予一个 IRI。这些图几乎 相同,但“Bob”的电子邮件地址发生了变化。
在此示例中,默认图用于记录来源信息, 实际读取的 RDF 数据保存在两个独立图中,每个图都由系统赋予一个 不同的 IRI。RDF 数据集由两个命名图和关于它们的 信息组成。
RDF 数据集:
# Default graph PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX g: <tag:example.org,2005-06-06:> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> g:graph1 dc:publisher "Bob" . g:graph1 dc:date "2004-12-06"^^xsd:date . g:graph2 dc:publisher "Bob" . g:graph2 dc:date "2005-01-10"^^xsd:date .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph1 PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph2 PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@newcorp.example.org> .
此查询查找电子邮件地址,并详细说明人员姓名以及发现该 信息的日期。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?name ?mbox ?date
WHERE {
?g dc:publisher ?name ;
dc:date ?date .
GRAPH ?g {
?person foaf:name ?name ; foaf:mbox ?mbox
}
}
结果表明“Bob”的电子邮件地址已经改变。
| name | mbox | date |
|---|---|---|
| "Bob" | <mailto:bob@oldcorp.example.org> | "2004-12-06"^^xsd:date |
| "Bob" | <mailto:bob@newcorp.example.org> | "2005-01-10"^^xsd:date |
本文档纳入了 SPARQL 联邦扩展的语法。
此特性定义于文档 SPARQL 1.1 联邦查询。
查询模式会生成一个无序的解集合,每个 解都是从变量到 RDF 项的偏函数。随后这些解被视为一个序列(解序列),初始时没有 特定顺序;之后应用任何序列修饰符来创建另一个序列。最后, 后一个序列用于生成 SPARQL 查询形式的某一种结果。
解序列修饰符是以下之一:
修饰符按上面列表给出的顺序应用。
ORDER BY 子句确定解序列的顺序。
ORDER BY 子句之后是一系列排序比较器,由
一个表达式和一个可选的排序修饰符(ASC() 或
DESC())组成。每个排序比较器要么是升序(由
ASC() 修饰符表示,或没有修饰符),要么是降序(由
DESC() 修饰符表示)。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
PREFIX : <http://example.org/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY DESC(?emp)
PREFIX : <http://example.org/ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY ?name DESC(?emp)
“<”运算符(见运算符
映射和运算符可扩展性)定义
numerics、
xsd:strings、xsd:booleans 和 xsd:dateTimes
成对值的相对顺序。IRI 对通过把它们作为数据类型为 xsd:string 的字面量进行比较来排序。
SPARQL 还在某些否则不会排序的 RDF 项种类之间固定了顺序:
SPARQL 并未定义所有可能 RDF 项的全序。实现可以 通过运算符可扩展性定义全序。以下是一些 相对顺序未定义的项对示例:
xsd:string 的字面量和一个带语言
标签的字面量)xsd:string 的字面量和一个带
受支持
数据类型的字面量)以下变量绑定列表按升序排列:
| RDF 项 | 原因 |
|---|---|
| 未绑定结果排序最靠前。 | |
_:z |
空白节点跟在未绑定之后。 |
_:a |
空白节点之间没有相对顺序。 |
<http://script.example/Latin> |
IRI 跟在空白节点之后。 |
<http://script.example/Кириллица> |
第 23 个位置的字符“К”的 unicode 码位为 0x41A,高于 0x4C(“L”)。 |
<http://script.example/漢字> |
第 23 个位置的字符“漢”的 unicode 码位为 0x6F22,高于 0x41A(“К”)。 |
"http://script.example/Latin" |
xsd:strings 跟在 IRI 之后。 |
两个解相对于某个排序比较器的升序,是通过将解绑定代入表达式, 并使用 “<”运算符比较它们来确定的。降序 是升序的反向。
两个解的相对顺序,是两个解相对于序列中第一个排序比较器的 相对顺序。对于那些解绑定的代入产生相同 RDF 项的解, 顺序是两个解相对于下一个排序比较器的相对 顺序。如果没有任何排序表达式在两个解上的求值产生 不同的 RDF 项,则两个解的相对顺序未定义。
对解序列排序总会得到一个包含相同数量 解的序列。
在 CONSTRUCT 或
DESCRIBE 查询的解序列上使用 ORDER BY 没有直接影响,
因为只有 SELECT 返回结果序列。与 LIMIT 和
OFFSET 结合使用时,
ORDER BY 可用于返回从解序列的不同切片生成的结果。
ASK 查询不包含 ORDER BY、
LIMIT 或 OFFSET。
解序列可以转换为只涉及变量子集的序列。 对于序列中的每个解,会使用 SELECT 查询形式指定选择的变量来形成 一个新解。
以下示例展示一个查询,用于使用 FOAF 属性从 RDF 图中提取所描述人员的姓名。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@work.example> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{ ?x foaf:name ?name }
| name |
|---|
| "Bob" |
| "Alice" |
没有 DISTINCT 或 REDUCED 查询修饰符的
解序列会保留重复解。
数据:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:x foaf:name "Alice" . _:x foaf:mbox <mailto:alice@example.com> . _:y foaf:name "Alice" . _:y foaf:mbox <mailto:asmith@example.com> . _:z foaf:name "Alice" . _:z foaf:mbox <mailto:alice.smith@example.com> .
查询:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name WHERE { ?x foaf:name ?name }
结果:
| name |
|---|
| "Alice" |
| "Alice" |
| "Alice" |
DISTINCT 和 REDUCED 修饰符会影响查询结果中
是否包含重复项。
DISTINCT 解修饰符会消除重复解。对于
将相同变量绑定到相同 RDF 项的解,查询只返回一个
解。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }
| name |
|---|
| "Alice" |
请注意,根据解 序列修饰符的顺序,重复项会在应用 limit 或 offset 之前被 消除。
DISTINCT 修饰符确保从解集中消除
重复解,而 REDUCED 只是允许消除它们。
REDUCED
解集中任何解的重数至少为一,且不超过在
没有 DISTINCT 或 REDUCED 修饰符的解集中的
该解重数。例如,使用上面的数据,查询
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT REDUCED ?name WHERE { ?x foaf:name ?name }
可能有一个、两个(此处显示)或三个解:
| name |
|---|
| "Alice" |
| "Alice" |
OFFSET 使生成的解从指定数量的
解之后开始。OFFSET 为零没有影响。
使用 LIMIT 和 OFFSET 选择查询
解的不同子集不会有用,除非通过使用 ORDER
BY 使顺序可预测。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
LIMIT 5
OFFSET 10
LIMIT 子句为返回的解数量设置上限。如果
在应用 OFFSET 后,实际解的数量大于该
限制,则最多返回该限制数量的解。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { ?x foaf:name ?name }
LIMIT 20
LIMIT 为 0 会导致不返回任何结果。limit 不得为
负数。
SPARQL 有四种查询形式。这些查询形式使用模式匹配得到的解来 形成结果集或 RDF 图。查询形式为:
- SELECT
- 返回查询模式匹配中绑定变量的全部或子集。
- CONSTRUCT
- 通过在一组三元组模板中替换变量,返回构造出的 RDF 图。
- ASK
- 返回一个布尔值,表示查询模式是否匹配。
- DESCRIBE
- 返回描述所找到资源的 RDF 图。
诸如 SPARQL 1.1 查询结果 JSON 格式、
SPARQL
查询结果 XML 格式(第二版)或
SPARQL 1.1 查询结果 CSV 和 TSV
格式等格式可用于序列化
SELECT 查询的结果集或 ASK 查询的布尔结果。
SELECT 结果形式直接返回变量及其绑定。它把 投影所需变量的操作与在查询解中引入新变量绑定的操作结合起来。
当在 SELECT 子句中给出变量名列表时,会返回
特定变量及其绑定。语法 SELECT * 是一种缩写,
它选择查询中该位置处于作用域内的所有变量。
它排除只在 FILTER 中使用的变量、MINUS 右侧
使用的变量,并考虑子查询。
只有当查询不使用分组时(无论是通过使用 GROUP BY 子句,
还是由于 HAVING 或 ORDER BY 子句中存在聚合),
才允许使用 SELECT *。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:knows _:b . _:a foaf:knows _:c . _:b foaf:name "Bob" . _:c foaf:name "Clare" . _:c foaf:nick "CT" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?nameX ?nameY ?nickY
WHERE
{ ?x foaf:knows ?y ;
foaf:name ?nameX .
?y foaf:name ?nameY .
OPTIONAL { ?y foaf:nick ?nickY }
}
| nameX | nameY | nickY |
|---|---|---|
| "Alice" | "Bob" | |
| "Alice" | "Clare" | "CT" |
结果集可以通过本地 API 访问,也可以序列化为 JSON、XML、CSV 或 TSV。
{
"head": {
"vars": [ "nameX" , "nameY" , "nickY" ]
} ,
"results": {
"bindings": [
{
"nameX": { "type": "literal" , "value": "Alice" } ,
"nameY": { "type": "literal" , "value": "Bob" }
} ,
{
"nameX": { "type": "literal" , "value": "Alice" } ,
"nameY": { "type": "literal" , "value": "Clare" } ,
"nickY": { "type": "literal" , "value": "CT" }
}
]
}
}
<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head>
<variable name="nameX"/>
<variable name="nameY"/>
<variable name="nickY"/>
</head>
<results>
<result>
<binding name="nameX">
<literal>Alice</literal>
</binding>
<binding name="nameY">
<literal>Bob</literal>
</binding>
</result>
<result>
<binding name="nameX">
<literal>Alice</literal>
</binding>
<binding name="nameY">
<literal>Clare</literal>
</binding>
<binding name="nickY">
<literal>CT</literal>
</binding>
</result>
</results>
</sparql>
除了选择模式匹配中的哪些变量包含在 结果中之外,SELECT 子句还可以引入新变量。SELECT 表达式中的赋值规则 与 BIND 中的赋值规则相同。表达式会组合查询解中已有的变量 绑定,或同一 SELECT 子句中更早定义的变量绑定,以在查询解中产生 一个绑定。
(expr AS v) 的作用域立即生效。在 SELECT
表达式中,该变量可以在同一
SELECT 子句后面的表达式中使用,并且不得在同一 SELECT
子句中再次赋值。
示例:
数据:
PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <http://example.org/book/> PREFIX ns: <http://example.org/ns#> :book1 dc:title "SPARQL Tutorial" . :book1 ns:price 42 . :book1 ns:discount 0.2 . :book2 dc:title "The Semantic Web" . :book2 ns:price 23 . :book2 ns:discount 0.25 .
查询:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title (?p*(1-?discount) AS ?price)
{ ?x ns:price ?p .
?x dc:title ?title .
?x ns:discount ?discount
}
结果:
| title | price |
|---|---|
| "The Semantic Web" | 17.25 |
| "SPARQL Tutorial" | 33.6 |
如果新变量在语法上于同一 SELECT 子句中更早引入, 也可以在表达式中使用:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX ns: <http://example.org/ns#>
SELECT ?title (?p AS ?fullPrice) (?fullPrice*(1-?discount) AS ?customerPrice)
{ ?x ns:price ?p .
?x dc:title ?title .
?x ns:discount ?discount
}
结果:
| title | fullPrice | customerPrice |
|---|---|---|
| "The Semantic Web" | 23 | 17.25 |
| "SPARQL Tutorial" | 42 | 33.6 |
CONSTRUCT 查询形式返回由图
模板指定的单个 RDF 图。结果是一个 RDF 图,其形成方式是对解序列中的每个查询解,
替换图模板中的变量,并通过集合并集将三元组
合并为一个单一 RDF 图。
如果任何这样的实例化产生了包含未绑定变量或非法 RDF 结构的三元组,例如字面量处于主语或谓语位置, 则该三元组不会包含在输出 RDF 图中。图模板可以包含没有变量的三元组 (称为基三元组或显式三元组),这些三元组也会出现在 CONSTRUCT 查询形式返回的输出 RDF 图中。
通过“集合并集”构造结果图并不 强制图序列化中是否出现重复三元组。 允许实现产生重复三元组或对其去重。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:mbox <mailto:alice@example.org> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
CONSTRUCT { <http://example.org/person#Alice> vcard:FN ?name }
WHERE { ?x foaf:name ?name }
从 FOAF 信息创建 vcard 属性:
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
<http://example.org/person#Alice> vcard:FN "Alice" .
模板可以创建包含空白节点的 RDF 图。 模板内的空白节点标识符对于每个解的作用域限定于 该模板,而来自查询解的空白节点 不受该作用域限制。 如果同一标识符在模板中出现两次,则每次出现 都会被替换为为每个 查询解创建的同一个空白节点,并且由不同查询解生成的三元组 会有不同的空白节点。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:givenname "Alice" . _:a foaf:family_name "Hacker" . _:b foaf:firstname "Bob" . _:b foaf:surname "Hacker" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
CONSTRUCT {
?x vcard:N _:v .
_:v vcard:givenName ?gname .
_:v vcard:familyName ?fname
} WHERE {
{ ?x foaf:firstname ?gname } UNION { ?x foaf:givenname ?gname } .
{ ?x foaf:surname ?fname } UNION { ?x foaf:family_name ?fname } .
}
创建与 FOAF 信息对应的 vcard 属性:
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
_:a vcard:N _:v1 .
_:v1 vcard:givenName "Alice" .
_:v1 vcard:familyName "Hacker" .
_:b vcard:N _:v2 .
_:v2 vcard:givenName "Bob" .
_:v2 vcard:familyName "Hacker" .
模板中标识符为 _:v 的空白节点
在模板应用于两个查询解中的每一个时,
会被不同的空白节点替换。
在此示例中,这会导致模板在
结果图中生成标识符为 _:v1 和 _:v2 的空白节点。
查询解中的空白节点,以标识符
_:a 和 _:b 显示,源自底层
RDF 数据集,不会被改变。
使用 CONSTRUCT,可以从目标 RDF 数据集中提取图的部分或全部。
第一个示例返回 IRI 标签为 http://example.org/aGraph 的图(如果它在数据集中);
否则返回一个空图。
CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <http://example.org/aGraph> { ?s ?p ?o } . }
对图的访问可以以其他信息为条件。例如,如果 默认图包含关于数据集中命名图的元数据,那么如下查询可以 基于有关命名图的信息提取一个图:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX app: <http://example.org/ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
CONSTRUCT { ?s ?p ?o } WHERE
{
GRAPH ?g { ?s ?p ?o } .
?g dc:publisher <http://www.w3.org/> .
?g dc:date ?date .
FILTER ( app:customDate(?date) > "2005-02-28T00:00:00Z"^^xsd:dateTime ) .
}
其中 app:customDate 标识一个扩展
函数,用于将日期格式转换为 xsd:dateTime RDF 项。
查询的解修饰符会影响 CONSTRUCT 查询的结果。
在此示例中,CONSTRUCT 模板的输出图仅来自
图模式匹配的两个解。该查询输出一个图,其中包含按 hits 排名前两个站点的人员姓名。
RDF 图中的三元组没有顺序。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX site: <http://example.org/stats#> _:a foaf:name "Alice" . _:a site:hits 2349 . _:b foaf:name "Bob" . _:b site:hits 105 . _:c foaf:name "Eve" . _:c site:hits 181 .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX site: <http://example.org/stats#>
CONSTRUCT { [] foaf:name ?name }
WHERE
{ [] foaf:name ?name ;
site:hits ?hits .
}
ORDER BY desc(?hits)
LIMIT 2
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:x foaf:name "Alice" .
_:y foaf:name "Eve" .
对于模板和模式相同,并且该模式只是一个基本图模式的情况,
提供了 CONSTRUCT 查询形式的简短形式(简短形式中不允许
FILTER,也不允许复杂图模式)。
简短形式中要求使用关键字 WHERE。
以下两个查询相同;第一个是第二个的简短形式。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
CONSTRUCT WHERE { ?x foaf:name ?name }
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
CONSTRUCT { ?x foaf:name ?name }
WHERE
{ ?x foaf:name ?name }
应用可以使用 ASK 形式来测试查询模式是否
有解。它不返回关于可能查询解的信息,只返回是否
存在解。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice" . _:a foaf:homepage <http://work.example.org/alice/> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ASK { ?x foaf:name "Alice" }
true
此结果集的 SPARQL 查询结果 XML 格式(第二 版)形式为:
<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head></head>
<boolean>true</boolean>
</sparql>
在相同数据上,以下查询返回不匹配,因为 Alice 的 mbox
未被提及。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
ASK {
?x foaf:name "Alice" ;
foaf:mbox <mailto:alice@work.example>
}
false
DESCRIBE 形式返回一个包含关于
资源的 RDF 数据的单个结果 RDF 图。该数据不是由 SPARQL 查询规定的,
因为查询客户端需要知道数据源中 RDF 的结构;相反,它由
SPARQL 查询处理器确定。查询模式用于创建结果集。
DESCRIBE 形式会取得解中标识的每个资源,
连同任何由 IRI 直接命名的资源,并通过获取一个
“描述”来组装单个 RDF 图,该描述可以来自包括目标 RDF 数据集在内的任何可用信息。
描述由查询服务确定。语法 DESCRIBE * 是一种
缩写,用于描述查询中的所有变量。
DESCRIBE 子句本身可以接受 IRI 来标识资源。
最简单的 DESCRIBE 查询就是 DESCRIBE
子句中的一个 IRI:
DESCRIBE <http://example.org/>
要描述的资源也可以从结果集中查询变量的绑定取得。 这使得无论资源在数据集中由 IRI 标识还是由空白节点标识, 都可以描述该资源:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE { ?x foaf:mbox <mailto:alice@org> }
属性 foaf:mbox 在 FOAF 词汇表中被定义为逆函数属性。
如果按此处理,此查询最多会返回关于一个人的信息。
但是,如果查询模式有多个解,则每个解的 RDF 数据是所有 RDF 图描述的并集。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE { ?x foaf:name "Alice" }
可以给出多个 IRI 或变量:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x ?y <http://example.org/>
WHERE {?x foaf:knows ?y}
返回的 RDF 由信息发布者确定。它可以是服务认为 与被描述资源相关的信息。它可以包含关于 其他资源的信息:例如,某本书的 RDF 数据也可能包含关于 作者的详细信息。
一个简单查询,例如
PREFIX ent: <http://org.example.com/employees#>
DESCRIBE ?x WHERE { ?x ent:employeeId "1234" }
可能返回该员工的描述以及其他一些潜在有用的 详细信息:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0>
PREFIX exOrg: <http://org.example.com/employees#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
_:a exOrg:employeeId "1234" ;
foaf:mbox_sha1sum "bee135d3af1e418104bc42904596fe148e90f033" ;
vcard:N
[ vcard:Family "Smith" ;
vcard:Given "John" ] .
foaf:mbox_sha1sum rdf:type owl:InverseFunctionalProperty .
其中包含
vCard 词汇表 vcard:N 的空白节点闭包。
决定返回哪些
信息的其他可能机制包括简明有界描述 [CBD]。
对于 FOAF 这样的词汇表,其中资源通常是空白节点,返回
足以标识节点的信息(例如 InverseFunctionalProperty
foaf:mbox_sha1sum)以及姓名和记录的其他详细信息,
会是适当的。在示例中,返回了与 WHERE 子句的匹配,
但这不是必需的。
SPARQL FILTER 会根据给定的
约束限制图模式匹配的解。具体而言,FILTER 会消除
这样的解:当把这些解代入表达式时,要么得到有效布尔值
false,要么产生错误。有效布尔值定义于
有效布尔值一节,错误定义于
求值错误。
RDF 字面量具有决定该字面量值的数据类型。
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> _:a a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:a dc:date "2004-12-31T19:00:00-05:00" . _:b a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:b dc:date "2004-12-31T19:01:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .
第一个 dc:date 三元组的宾语是一个
数据类型为 xsd:string 的字面量。
第二个具有数据类型 xsd:dateTime。
它们是不同的 RDF 项,
具有不同的值。
SPARQL 表达式按照文法构造,并提供对函数(由 IRI 命名)和 运算符函数(由 SPARQL 文法中的关键字和符号调用)的访问。SPARQL 运算符可用于比较字面量的值:
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?annot
WHERE { ?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> .
?annot dc:date ?date .
FILTER ( ?date > "2005-01-01T00:00:00Z"^^xsd:dateTime )
}
SPARQL 运算符列于第 17.3 节,并与文法中的 相应产生式相关联。
此外,SPARQL 提供调用任意函数的能力,包括 第 17.5 节列出的一部分 XPath 转换函数。这些 函数在 SPARQL 查询中按名称(一个 IRI)调用。例如:
... FILTER ( xsd:dateTime(?date) < xsd:dateTime("2005-01-01T00:00:00Z") ) ...
排版约定:XPath 运算符用前缀
op: 标记。XPath 运算符没有命名空间;op: 是一种标记
约定。
在 SPARQL 中,XPath 和 XQuery 函数与运算符 3.1 [XPATH-FUNCTIONS-31] 中依赖 XML 和 XML Schema 的定义 必须使用 可扩展标记语言(XML)1.1(第二版) [XML11] 和 W3C XML Schema 定义语言(XSD)1.1 第 2 部分:数据类型 [XMLSCHEMA11-2]
XML 1.0 与 1.1 以及 XML Schema 1.0 与 1.1 的使用,在
XPath 和 XQuery 函数与运算符
3.1中是
由实现定义的。
这尤其影响 Char 的定义,
该定义在 可扩展标记语言(XML)1.1(第二
版)中更为通用。
SPARQL 函数和运算符作用于 RDF 项和 SPARQL 变量。其中一部分
函数和运算符取自 XPath 和 XQuery 函数与运算符
3.1 [XPATH-FUNCTIONS-31],并具有 XML
Schema
类型化
值参数和返回类型。作为参数传给这些函数和运算符的 RDF
literals 会映射为 XML Schema 类型化值,其
字符串值为
lexical form,并具有与
datatype IRI 对应的
原子数据类型。返回的类型化值会以相同方式映射回
RDF literals。
SPARQL 还有一些作用于 RDF 项特定子集的附加运算符。引用
类型时,以下术语表示具有相应 W3C XML Schema 定义语言(XSD)1.1 第 2 部分:
数据类型 [XMLSCHEMA11-2]
datatype
IRI 的 literal:
以下术语标识 SPARQL 值测试中使用的附加类型:
xsd:integer、xsd:decimal、xsd:float 或
xsd:double。
以下类型派生自 numeric 类型,并且是接受 numeric 参数的函数和运算符的有效参数:
xsd:nonPositiveInteger
xsd:negativeInteger
xsd:long
xsd:int
xsd:short
xsd:byte
xsd:nonNegativeInteger
xsd:unsignedLong
xsd:unsignedInt
xsd:unsignedShort
xsd:unsignedByte
xsd:positiveInteger
SPARQL 语言扩展可以将附加类型视为派生自 XML schema 数据类型。
SPARQL 表达式相对于一个解映射, 并在具有活动图的 RDF 数据集上下文中进行求值。 这种求值的结果要么是一个 RDF 项,要么是一个 错误。
SPARQL 提供由 XPath 和 XQuery 函数与 运算符定义的函数和运算符的一个子集。 以下规则适配 XPath/XQuery 与 SPARQL 之间数据模型和执行模型的差异:
xsd:boolean。
||)、
logical-and(&&)、
logical-not(!)、
NOT EXISTS、
EXISTS 和
EBV之外,
所有函数都作用于 RDF 项。
如果任何参数未绑定,函数会产生一个错误。
||)
或 logical-and(&&)之外,任何遇到
错误的表达式都会产生该错误。
true(T)、false (F)和 error(E)的 logical-and 与 logical-or 真值表如下:
| A | B | A || B | A && B |
|---|---|---|---|
| T | T | T | T |
| T | F | T | F |
| F | T | T | F |
| F | F | F | F |
| T | E | T | E |
| E | T | T | E |
| F | E | E | F |
| E | F | E | F |
| E | E | E | E |
SPARQL 定义了用于在参数列表上调用函数的语法。除非另有 说明,这些函数按如下方式调用:
如果这些步骤中的任何一个失败,该调用就会生成错误。错误的影响 定义于 17.2 表达式求值一节。
还存在“函数形式”,其求值规则不同于 函数,具体由每个这样的形式规定。
表达式的求值可能导致 错误, 例如函数的参数是错误数据类型的字面量, 或参数是错误种类的 RDF 项时。
如果表达式的求值引发错误,则包含 该错误表达式的每个函数、运算符和表达式的 求值也会引发错误。 某些函数形式 会按其定义中的描述处理错误。
有效布尔值用于计算传给逻辑函数
logical-and、logical-or
和 logical-not 的参数,
也用于求值 FILTER 表达式的结果。
xsd:boolean EBV (RDF term term)
xsd:boolean,且具有
有效词汇形式,则 EBV 函数返回该参数。
NaN 或数值上等于零时,
EBV 函数返回字面量 "false"^^xsd:boolean;
否则 EBV 函数返回字面量 "true"^^xsd:boolean。
xsd:string 且值等于空字符串,
则 EBV 函数返回字面量 "false"^^xsd:boolean;
否则 EBV 函数返回字面量 "true"^^xsd:boolean。
xsd:boolean,
也不是 numeric 数据类型,
也不是 xsd:string,则引发一个错误。
| 示例 | EBV 值 |
|---|---|
| EBV("true"^^xsd:boolean) | true |
| EBV("") | false |
| EBV("1"^^xsd:boolean) | true |
| EBV(-2e10) | true |
| EBV(-0) | false |
| EBV(<http://example/>) | error |
| EBV("2025-08-18"^^xsd:date) | error |
true 的 EBV 表示为一个
literal,
其 datatype IRI 为 xsd:boolean,词汇值为 "true";
false 的 EBV 表示为一个
literal,
其 datatype IRI 为 xsd:boolean,词汇值为 "false"。
SPARQL 文法标识一组用于构造约束的运算符
(例如 &&、
*、isIRI)。
下表将每个这样的文法产生式与适当的操作数,以及由
XPath 和 XQuery 函数与运算符
3.1 [XPATH-FUNCTIONS-31] 或
第
17.4 节中指定的 SPARQL 运算符所定义的运算符函数相关联。在为给定参数集选择运算符定义时,
具有最具体参数的定义适用。例如,在求值
xsd:integer = xsd:signedInt 时,适用的是带有两个
numeric 参数的 = 定义,而不是带有两个
RDF terms 的定义。该表经过排列,使最上方可行的
候选项最具体。没有适当操作数而调用的运算符
会导致一个错误。
SPARQL 遵循 XPath 对数值运算符参数进行数值类型提升和子类型替换的方案。
XPath
运算符映射
中用于 numeric 操作数(xsd:integer、
xsd:decimal、xsd:float、xsd:double 以及派生自
numeric 类型的类型)的规则同样适用于 SPARQL 运算符(见
XML 路径语言
(XPath)3.1 [XPATH-31] 中
数值类型
提升和子类型替换的定义)。
某些运算符与嵌套函数表达式相关联,例如
fn:not(op:numeric-equal(A, B))。请注意,根据 XPath 定义,
如果参数是错误,fn:not 和 op:numeric-equal 会产生错误。
fn:compare 的排序规则由
XPath 定义,并由
http://www.w3.org/2005/xpath-functions/collation/codepoint 标识。该排序规则
允许基于码位值进行字符串比较。码位字符串等价性可以
用 RDF term 等价性来测试。
| 运算符 | Type(A) | 函数 | 结果类型 |
|---|---|---|---|
| XQuery 一元运算符 | |||
| ! A | xsd:boolean (EBV) | logical-not(A) | xsd:boolean |
| + A | numeric | op:numeric-unary-plus(A) | numeric |
| - A | numeric | op:numeric-unary-minus(A) | numeric |
| 运算符 | Type(A) | Type(B) | 函数 | 结果类型 |
|---|---|---|---|---|
| 逻辑连接词 | ||||
| A || B | xsd:boolean (EBV) | xsd:boolean (EBV) | logical-or(A, B) | xsd:boolean |
| A && B | xsd:boolean (EBV) | xsd:boolean (EBV) | logical-and(A, B) | xsd:boolean |
| XPath 测试 | ||||
| A = B | numeric | numeric | op:numeric-equal(A, B) | xsd:boolean |
| A = B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), 0) | xsd:boolean |
| A = B | xsd:boolean | xsd:boolean | op:boolean-equal(A, B) | xsd:boolean |
| A = B | xsd:dateTime | xsd:dateTime | op:dateTime-equal(A, B) | xsd:boolean |
| A != B | numeric | numeric | fn:not(op:numeric-equal(A, B)) | xsd:boolean |
| A != B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 0)) | xsd:boolean |
| A != B | xsd:boolean | xsd:boolean | fn:not(op:boolean-equal(A, B)) | xsd:boolean |
| A != B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-equal(A, B)) | xsd:boolean |
| A < B | numeric | numeric | op:numeric-less-than(A, B) | xsd:boolean |
| A < B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), -1) | xsd:boolean |
| A < B | xsd:boolean | xsd:boolean | op:boolean-less-than(A, B) | xsd:boolean |
| A < B | xsd:dateTime | xsd:dateTime | op:dateTime-less-than(A, B) | xsd:boolean |
| A > B | numeric | numeric | op:numeric-greater-than(A, B) | xsd:boolean |
| A > B | xsd:string | xsd:string | op:numeric-equal(fn:compare(STR(A), STR(B)), 1) | xsd:boolean |
| A > B | xsd:boolean | xsd:boolean | op:boolean-greater-than(A, B) | xsd:boolean |
| A > B | xsd:dateTime | xsd:dateTime | op:dateTime-greater-than(A, B) | xsd:boolean |
| A <= B | numeric | numeric | logical-or(op:numeric-less-than(A, B), op:numeric-equal(A, B)) | xsd:boolean |
| A <= B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 1)) | xsd:boolean |
| A <= B | xsd:boolean | xsd:boolean | fn:not(op:boolean-greater-than(A, B)) | xsd:boolean |
| A <= B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-greater-than(A, B)) | xsd:boolean |
| A >= B | numeric | numeric | logical-or(op:numeric-greater-than(A, B), op:numeric-equal(A, B)) | xsd:boolean |
| A >= B | xsd:string | xsd:string | fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), -1)) | xsd:boolean |
| A >= B | xsd:boolean | xsd:boolean | fn:not(op:boolean-less-than(A, B)) | xsd:boolean |
| A >= B | xsd:dateTime | xsd:dateTime | fn:not(op:dateTime-less-than(A, B)) | xsd:boolean |
| XPath 算术 | ||||
| A * B | numeric | numeric | op:numeric-multiply(A, B) | numeric |
| A / B | numeric | numeric | op:numeric-divide(A, B) | numeric;但如果两个操作数都是 xsd:integer,则为 xsd:decimal |
| A + B | numeric | numeric | op:numeric-add(A, B) | numeric |
| A - B | numeric | numeric | op:numeric-subtract(A, B) | numeric |
| SPARQL 测试 | ||||
| A = B | IRI | IRI | sameTerm(A, B) | xsd:boolean |
| A = B | Blank Node | Blank Node | sameTerm(A, B) | xsd:boolean |
| A = B | Triple Term | Triple Term |
( A.subject = B.subject ) && ( A.predicate = B.predicate ) && ( A.object = B.object ) |
xsd:boolean |
| A != B | IRI | IRI | fn:not(sameTerm(A, B)) | xsd:boolean |
| A != B | Blank Node | Blank Node | fn:not(sameTerm(A, B) | xsd:boolean |
| A != B | Triple Term | Triple Term |
( A.subject != B.subject ) || ( A.predicate != B.predicate ) || ( A.object != B.object ) |
xsd:boolean |
| A = B | RDF term | RDF term | sameValue(A, B) | xsd:boolean |
| A != B | RDF term | RDF term | fn:not(sameValue(A, B)) | xsd:boolean |
标有“(EBV)”的 xsd:boolean 函数参数, 会通过求值该参数的有效布尔值而强制转换为 xsd:boolean。
应用于 三元组项的 运算符 = 和 != 会把该运算符应用于各组成部分。
SPARQL 语言扩展可以提供运算符与
运算符函数之间的附加关联;这相当于向上表添加行。任何附加运算符
不得产生会替换除错误以外任何结果的结果。
该规则的结果是,SPARQL FILTER 在应用
FILTER 之后会产生与未扩展实现
至少相同的中间绑定。
预期“<”运算符的附加映射用于控制操作数的相对顺序,
尤其是在 ORDER
BY 子句中使用时。
本节定义由 SPARQL 查询语言引入的运算符和函数。 示例展示这些运算符在由适当文法结构调用时的行为。
xsd:boolean BOUND (variable var)
如果 var 被绑定到一个值,则返回 true。
否则返回 false。值为 NaN 或 INF 的变量被视为已绑定。
数据:
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> _:a foaf:givenName "Alice". _:b foaf:givenName "Bob" . _:b dc:date "2005-04-04T04:04:04Z"^^xsd:dateTime .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?givenName
WHERE {
?x foaf:givenName ?givenName .
OPTIONAL { ?x dc:date ?date } .
FILTER ( bound(?date) )
}
查询结果:
| givenName |
|---|
| "Bob" |
可以通过指定一个
OPTIONAL 图模式来测试某个图模式是否
未被表达,该图模式引入一个变量,然后测试该变量是否未
绑定。
这在逻辑编程中称为失败即否定。
此查询匹配具有 name 但没有表达
date 的人员:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?name
WHERE {
?x foaf:givenName ?name .
OPTIONAL { ?x dc:date ?date } .
FILTER (!bound(?date))
}
查询结果:
| name |
|---|
| "Alice" |
由于 Bob 的 dc:date 是已知的,"Bob" 不是该查询的解。
rdfTerm IF (expression1, expression2, expression3)
IF 函数形式对第一个参数求值,将其解释为
有效布尔值,然后如果 EBV 为 true,则返回
expression2 的值;否则返回
expression3 的值。expression2 和
expression3 中只有一个会被求值。如果对第一个参数求值引发错误,
则对 IF 表达式求值会引发一个错误。
示例:假设在某个查询解中,?x 绑定到 2,?z
绑定到 0,
并且 ?y 未绑定:
IF(?x = 2, "yes", "no") |
返回 "yes" |
IF(bound(?y), "yes", "no") |
返回 "no" |
IF(?x=2, "yes", 1/?z) |
返回 "yes",表达式 1/?z 不会被求值 |
IF(?x=1, "yes", 1/?z) |
引发错误 |
IF("2" > 1, "yes", "no") |
引发错误 |
rdfTerm COALESCE(expression, ....)
COALESCE 函数形式返回第一个求值不产生错误的
表达式的 RDF 项值。
在 SPARQL 中,对未绑定变量求值会引发错误。
如果没有任何表达式求值时不产生错误,则引发错误。
如果表达式数量为零,则引发错误。
示例:假设在某个查询解中 ?x = 2 且 ?y 未绑定:
COALESCE(?x, 1/0) |
返回 2,即 x 的值 |
COALESCE(1/0, ?x) |
返回 2 |
COALESCE(5, ?x) |
返回 5 |
COALESCE(?y, 3) |
返回 3 |
COALESCE(?y) |
引发错误,因为 y 未绑定。 |
COALESCE() |
引发错误,因为参数数量为零。 |
有一个过滤器运算符 EXISTS,它接受一个图模式。
EXISTS 返回 true 或 false,
具体取决于该模式与解映射一起是否匹配数据集。
不会发生变量的额外绑定。NOT EXISTS 形式
会转换为
fn:not(EXISTS {...})。
xsd:boolean NOT EXISTS { pattern }
如果 pattern 匹配,则返回 false。
否则返回 true。
NOT EXISTS { pattern } 等价于 fn:not(EXISTS { pattern
})。
xsd:boolean EXISTS { pattern }
如果 pattern 匹配,则返回 true。
否则返回 false。
形式上,对于每个形式为 EXISTS { pattern } 的
表达式 expr,
相对于解映射 μ、
在具有活动图 G 的
数据集 D上下文中
求值 expr 的结果为:
其中 A 是按照18.3
到代数
语法的转换,通过转换 { pattern } 获得的
代数查询表达式。
按照文法中的
ExistsFunc 产生式,
{ pattern } 匹配 GroupGraphPattern
产生式。
18.3
到代数语法的转换中涵盖任何
GroupGraphPattern 转换的具体小节
是18.3.2.6 转换图模式。
xsd:boolean logical-or (xsd:boolean left, xsd:boolean right)
此函数不能在表达式中直接使用。
此函数的目的是定义“||”运算符的语义。
该函数返回 left 和 right 的逻辑
OR。请注意,logical-or
作用于其每个参数的有效布尔值。
注:关于 || 运算符如何处理错误,见
17.2
表达式求值一节。
xsd:boolean logical-and (xsd:boolean left, xsd:boolean right)
此函数不能在表达式中直接使用。
此函数的目的是定义“&&”
运算符的语义。
该函数返回 left 和 right 的逻辑
AND。请注意,logical-and
作用于其每个参数的有效布尔值。
注:关于 && 运算符如何处理错误,见
17.2
表达式求值一节。
xsd:boolean logical-not (xsd:boolean arg)
此函数不能在表达式中直接使用。此函数的目的是
定义“!”运算符的语义。
该函数返回 arg 的逻辑 NOT。
请注意,logical-not 作用于其
参数的有效布尔值。
boolean rdfTerm IN (expression, ...)
IN 运算符测试左侧的 RDF 项是否出现在
右侧表达式值的列表中。该测试使用 “=” 运算符完成,
后者按照运算符映射所确定的方式
测试是否为同一值。
右侧含有零个项的列表是合法的,并且求值为
false。
比较中的错误会导致 IN 表达式
引发错误,前提是正在测试的 RDF 项未在该项列表的
其他位置找到。
如果 IN 与一个表达式一起用于产生
rdfTerm,则该表达式只会在求值 IN
表达式之前求值一次。
IN 运算符等价于以下
SPARQL 表达式:
(rdfTerm = value of expression1) || (rdfTerm = value of expression2) || ...
示例:
2 IN (1, 2, 3) |
true |
2 IN () |
false |
2 IN (<http://example/iri>, "str", 2.0) |
true |
2 IN (1/0, 2) |
true |
2 IN (2, 1/0) |
true |
2 IN (3, 1/0) |
引发错误 |
boolean rdfTerm NOT IN (expression, ...)
NOT IN 运算符测试左侧的 RDF 项是否
未出现在右侧表达式列表的值中。该测试使用 “!=”
运算符完成,后者按照
运算符映射所确定的方式
测试两个值是否不是同一值。
右侧含有零个项的列表是合法的,并且求值为
true。
如果 NOT IN 与一个表达式一起用于产生
rdfTerm,则该表达式只会在求值 NOT IN
表达式之前求值一次。
比较中的错误会导致 NOT IN 表达式引发错误,前提是
正在测试的 RDF 项未在该项列表的其他位置找到。
NOT IN 运算符等价于以下
SPARQL 表达式:
(rdfTerm != value of expression1) && (rdfTerm != value of expression2) && ...
NOT IN (...) 等价于 !(IN (...))。
示例:
2 NOT IN (1, 2, 3) |
false |
2 NOT IN () |
true |
2 NOT IN (<http://example/iri>, "str", 2.0) |
false |
2 NOT IN (1/0, 2) |
false |
2 NOT IN (2, 1/0) |
false |
2 NOT IN (3, 1/0) |
引发错误 |
xsd:boolean sameTerm (RDF term term1, RDF term term2)
如果 term1 和 term2 是
RDF 1.2 概念与抽象数据
模型 [RDF12-CONCEPTS] 中定义的同一
RDF 项,则返回 TRUE;否则返回 FALSE。
如果以下任一条件为 true,则 term1 和 term2 是 同一 RDF 项:
term1 和 term2 是作为
IRI 相同的
IRI。
term1 和 term2 是作为
字面量项相等的
literals。
term1 和 term2 是作为
空白节点相等的
blank nodes。
term1 和 term2 是作为
三元组相等的
triple terms;
也就是说,
subject、
predicate 和
object
组成部分两两为同一项。
sameTerm(<http://example/>, <http://example/>) |
true |
sameTerm(<http://example/>, <https://example/>) |
false |
sameTerm("abc", "abc") |
true |
sameTerm("abc"@en, "abc") |
false |
sameTerm("abc"@en, "abc"@EN) |
true |
sameTerm("abc"@en--rtl, "abc"@en) |
false |
sameTerm(2, 2.0) |
false |
sameTerm(2, "2"^^xsd:integer) |
true |
sameTerm(2, "02"^^xsd:integer) |
false |
此函数取代 SPARQL 1.1 中的 RDFterm-equal。
xsd:boolean sameValue (RDF term term1, RDF term term2)
此函数不能在表达式中直接使用。此函数的目的是 在 “=” 运算符应用于两个 RDF 项,且它们不属于 17.3 运算符 映射一节中运算符映射表所涵盖的具体情形时, 定义该运算符的语义。
此函数的结果通过执行以下步骤确定。
term1 和 term2 是
相等的 RDF 项,
则返回 TRUE。
term1 或 term2 是
IRI 或
blank node,
则返回 FALSE。
term1 和 term2 中恰好一个是
triple term,
则返回 FALSE。
term1 和 term2 都是
triple terms,
则将 sameValue 函数两两应用于每个组成部分。
如果每个组成部分对都返回 TRUE,则返回 TRUE;
如果任何组成部分对产生错误,
则产生一个错误;
否则返回 FALSE。
term1 和 term2 都是
literals,
且其中一个或两个字面量已知为
病态类型,
则产生一个错误。
"NaN"^^xsd:double 和 "NaN"^^xsd:float 被视为
表示同一值。
如果 term1 和 term2 对于 xsd:double 或 xsd:float
均为 "NaN",则返回 TRUE。
term1 和 term2 都是
literals,
且 SPARQL 处理器能够确定它们的值相等,
则返回 TRUE。
term1 和 term2 都是
literals,
且 SPARQL 处理器能够确定它们的值
不相等,则返回 FALSE。
如果两个参数都是字面量,则在 SPARQL 处理器能够确定
这些字面量的值相等或不相等的情况下,函数
sameValue 返回 true 或 false。
如果 SPARQL 处理器无法确定,则返回 error。
对于 xsd:double 和 xsd:float,+0、-0 和 0 是同一
值。
“=”的运算符映射
是函数
op:numeric-equal,
其定义是在比较涉及 NaN 的参数时返回 false。
然而,sameTerm("NaN"^^xsd:double, "NaN"^^xsd:double) 为 true。
函数 sameValue 将
sameValue("NaN"^^xsd:double, "NaN"^^xsd:double)
定义为 true,因为这些参数是值空间中的同一元素。
类似地,函数 sameValue 将
sameValue("NaN"^^xsd:float, "NaN"^^xsd:float)
定义为 true。
sameValue 将 "NaN"^^xsd:double 和
"NaN"^^xsd:float 的值视为同一值。
sameValue("NaN"^^xsd:double, "NaN"^^xsd:float) 和
sameValue("NaN"^^xsd:float, "NaN"^^xsd:double) 都为 true。
示例:
| sameValue | 结果 |
|---|---|
sameValue(1e10, "NaN"^^xsd:double) |
false |
sameValue("NaN"^^xsd:double, "NaN"^^xsd:double) |
true |
sameValue("NaN"^^xsd:double, "NaN"^^xsd:float) |
true |
sameValue( <<(:s :p 123)>> , <<(:s :p 123.0)>> )
|
true |
扩展实现可以支持字面量的附加数据类型。处理一个查询的实现,
在测试具有未识别数据类型(且词汇形式和 datatype IRI
不相同)的字面量是否等价时,会返回错误,表示它无法确定
被比较字面量的值是否等价。例如,未扩展的实现
在测试 "iiii"^^my:romanNumeral =
"iv"^^my:romanNumeral 时会产生错误。
xsd:boolean isIRI (RDF term term) xsd:boolean isURI (RDF term term)
如果 term 是一个
IRI,则返回 true。
否则返回 false。
isURI 是
isIRI 运算符的另一种拼写。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice". _:a foaf:mbox <mailto:alice@work.example> . _:b foaf:name "Bob" . _:b foaf:mbox "bob@work.example" .
此查询匹配具有 name 和 mbox 且
mbox 是 IRI 的人员:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name ;
foaf:mbox ?mbox .
FILTER isIRI(?mbox)
}
查询结果:
| name | mbox |
|---|---|
| "Alice" | <mailto:alice@work.example> |
xsd:boolean isBLANK (RDF term term)
如果 term 是一个 blank
node,则返回 true。否则返回 false。
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:a dc:creator "Alice B. Toeclips" . _:b a:annotates <http://www.w3.org/TR/rdf-sparql-query/> . _:b dc:creator _:c . _:c foaf:given "Bob". _:c foaf:family "Smith".
此查询匹配其 dc:creator 使用来自 FOAF 词汇表的谓词来表达
姓名的人员。
PREFIX a: <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?given ?family
WHERE {
?annot a:annotates <http://www.w3.org/TR/rdf-sparql-query/> .
?annot dc:creator ?c .
OPTIONAL { ?c foaf:given ?given ; foaf:family ?family } .
FILTER isBLANK(?c)
}
查询结果:
| given | family |
|---|---|
| "Bob" | "Smith" |
在此示例中,dc:creator 谓词有两个宾语,但
只有一个(_:c)是空白节点。
xsd:boolean isLITERAL (RDF term term)
如果 term 是一个 literal,则返回
true。否则返回 false。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:a foaf:name "Alice".
_:a foaf:mbox <mailto:alice@work.example> .
_:b foaf:name "Bob" .
_:b foaf:mbox "bob@work.example" .
此查询类似于 17.4.2.1 中的查询,
但它匹配具有 name 和 mbox 且
mbox 是字面量的人员。这可用于查找错误数据
(foaf:mbox 应该只把 IRI 作为其宾语)。
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name ;
foaf:mbox ?mbox .
FILTER isLiteral(?mbox)
}
查询结果:
| name | mbox |
|---|---|
| "Bob" | "bob@work.example" |
xsd:boolean isNUMERIC (RDF term term)
如果 term 是数值,则返回 true。
否则返回 false。如果 term 具有适当的数据类型
(见操作数数据类型一节)并且具有
有效词汇形式,使其成为接受数值参数的函数和运算符的有效参数,
则 term 是数值。
示例:
isNUMERIC(12) |
true |
isNUMERIC("12") |
false |
isNUMERIC("12"^^xsd:nonNegativeInteger) |
true |
isNUMERIC("1200"^^xsd:byte) |
false |
isNUMERIC(<http://example/>) |
false |
xsd:string STR (literal literal) xsd:string STR (IRI rsrc)
返回 literal(一个 literal)的
词汇形式;返回
rsrc(一个 IRI)的码位表示。这有助于检查
IRI 的各个部分,例如主机名。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice". _:a foaf:mbox <mailto:alice@work.example> . _:b foaf:name "Bob" . _:b foaf:mbox <mailto:bob@home.example> .
此查询选择在其 foaf 资料中使用 work.example
地址的人员集合:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name ;
foaf:mbox ?mbox .
FILTER regex(str(?mbox), "@work\\.example$")
}
查询结果:
| name | mbox |
|---|---|
| "Alice" | <mailto:alice@work.example> |
xsd:string LANG (literal ltrl)
如果 ltrl 具有
语言标签,
则返回它的语言标签。
如果 ltrl 没有
语言标签,
则返回空字符串。
请注意,RDF 数据模型不包含具有空
语言标签的字面量。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Robert"@en. _:a foaf:name "Roberto"@es. _:a foaf:mbox <mailto:bob@work.example> .
此查询查找西班牙语 foaf:name 和 foaf:mbox:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
?x foaf:name ?name ;
foaf:mbox ?mbox .
FILTER ( lang(?name) = "es" )
}
查询结果:
| name | mbox |
|---|---|
| "Roberto"@es | <mailto:bob@work.example> |
函数示例:
| 表达式 | 结果 |
|---|---|
LANG("abc"@en) |
"en" |
LANG("abc"@en--ltr) |
"en" |
LANG("abc") |
"" |
LANG(1) |
"" |
LANG(<http://example/>) |
error |
xsd:string LANGDIR (literal ltrl)
如果 ltrl 具有
基方向,
则返回它的基方向。
如果 ltrl 没有
基方向,
则返回空字符串。
请注意,RDF 数据模型不包含具有空
基方向的字面量。
| 表达式 | 结果 |
|---|---|
LANGDIR("abc"@en--ltr) |
"ltr" |
LANGDIR("abc"@en) |
"" |
LANGDIR("abc") |
"" |
LANGDIR(1) |
"" |
LANGDIR(<http://example/>) |
error |
xsd:string hasLANG (RDF term term)
如果 RDF 项参数是带有
语言标签的字面量,
则返回 true。
否则,该函数返回 false。
如果参数是字面量,则该函数等价于
测试该字面量的数据类型是否为
rdf:langString 或 rdf:dirLangString。
| 表达式 | 结果 |
|---|---|
hasLANG("abc"@en) |
true |
hasLANG("abc@"en--ltr) |
true |
hasLANG("تصميم المواقع"@ar--rtl) |
true |
hasLANG(1) |
false |
hasLANG(<http://example/>) |
false |
xsd:string hasLANGDIR (RDF term term)
如果 RDF 项参数是带有
基方向的字面量,
则返回 true。
否则,该函数返回 false。
如果参数是字面量,则该函数等价于
测试该字面量的数据类型是否为
rdf:dirLangString。
| 表达式 | 结果 |
|---|---|
hasLANGDIR("abc"@en) |
false |
hasLANGDIR("abc@"en--ltr) |
true |
hasLANGDIR("تصميم المواقع"@ar--rtl) |
true |
hasLANGDIR(1) |
false |
hasLANGDIR(<http://example/>) |
false |
iri DATATYPE (literal literal)
返回给定字面量的 datatype IRI。
具有
语言标签
且没有
基方向的字面量的
datatype IRI
是 rdf:langString。
具有
语言标签
和
基方向
的字面量的
datatype IRI
是 rdf:dirLangString。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX eg: <http://biometrics.example/ns#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> _:a foaf:name "Alice". _:a eg:shoeSize "9.5"^^xsd:float . _:b foaf:name "Bob". _:b eg:shoeSize "42"^^xsd:integer .
此查询查找所有 shoeSize 为整数的人员的
foaf:name 和 foaf:shoeSize:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX eg: <http://biometrics.example/ns#>
SELECT ?name ?shoeSize
WHERE {
?x foaf:name ?name ;
eg:shoeSize ?shoeSize .
FILTER ( datatype(?shoeSize) = xsd:integer )
}
查询结果:
| name | shoeSize |
|---|---|
| "Bob" | 42 |
iri IRI(xsd:string) iri IRI(iri) iri URI(xsd:string) iri URI(iri)
IRI 函数通过解析字符串参数来构造 IRI(见
[RFC3986] 和
[RFC3987],或任何取代
RFC 3986 或 RFC 3987 的后续 RFC)。该
IRI 会相对于查询的基 IRI 解析,并且必须得到一个绝对 IRI。
URI 函数是 IRI 的同义词。
如果传给该函数的是 IRI,则它原样返回该 IRI。
传入除数据类型为 xsd:string 的字面量或 IRI 之外的任何 RDF 项,都是
错误。
实现可以规范化该 IRI。
示例:
IRI("http://example/") |
<http://example/> |
IRI(<http://example/>) |
<http://example/> |
blank node BNODE()
blank node BNODE(xsd:string)
BNODE 函数构造一个空白节点,它不同于
被查询数据集中的所有空白节点,也不同于为其他查询解调用
此构造器所创建的所有空白节点。如果使用无参数形式,
每次调用都会产生一个不同的空白节点。如果使用带有 xsd:string 字面量的形式,
则对于不同的 xsd:string 字面量,每次调用都会产生不同的空白节点;而在一个
解映射的表达式中,
使用相同 xsd:string 字面量调用时会得到同一个空白节点。
此功能与 SPARQL CONSTRUCT 模板中对 空白节点的处理兼容。
literal STRDT(xsd:string lexicalForm, IRI datatypeIRI)
STRDT 函数按照参数所指定的
词汇形式
和
datatype IRI
构造一个字面量。
| 表达式 | 结果 |
|---|---|
STRDT("123", xsd:integer) |
"123"^^<http://www.w3.org/2001/XMLSchema#integer> |
STRDT("iiii", <http://example/romanNumeral>) |
"iiii"^^<http://example/romanNumeral> |
datatypeIRI 参数
rdf:langString 或 rdf:dirLangString 调用
STRDT。若要创建以这些 IRI 作为 datatype IRI 的字面量,
应使用函数 STRLANG
或 STRLANGDIR。
literal STRLANG(xsd:string lexicalForm, xsd:string langTag)
STRLANG 函数按照参数所指定的
词汇形式
和
语言标签
构造一个字面量,
并带有 rdf:langString 的 datatype IRI。
参数 langTag 不得为空字符串,并且应该是
有效的语言标签。
| 表达式 | 结果 |
|---|---|
STRLANG("chat", "fr") |
"chat"@fr |
STRLANG("abc", "") |
error |
STRLANG(123, "en") |
error |
literal STRLANGDIR(xsd:string lexicalForm, xsd:string langTag, xsd:string baseDirection)
STRLANGDIR 函数按照参数所指定的
词汇形式、
语言标签和
基方向
构造一个字面量,
并带有 rdf:dirLangString 的 datatype IRI。
参数 langTag 不得为空字符串,并且应该是
有效的语言标签。
参数 baseDirection 必须是
"ltr" 或 "rtl"。
| 表达式 | 结果 |
|---|---|
STRLANGDIR("abc", "en", "ltr") |
"abc"@en--ltr |
STRLANGDIR("abc", "en", "LTR") |
error |
STRLANGDIR("قطة", "ar", "rtl") |
"قطة"@ar--rlt |
STRLANGDIR("abc", "en", "") |
error |
STRLANGDIR("abc", "", "ltr") |
error |
STRLANGDIR(123, "", "ltr") |
error |
STRLANGDIR(<x:uri>, "en", "ltr") |
error |
iri UUID()
返回来自 通用唯一标识符(UUID)URN
命名空间的全新 IRI。每次调用 UUID() 都会返回一个
不同的 UUID。它不得是 “nil” UUID(全为零)。UUID 的变体和版本
由实现决定。
UUID() |
<urn:uuid:b9302fb5-642e-4d3b-af19-29a8f6d894c9> |
xsd:string STRUUID()
返回一个字符串,即 UUID 的方案特定部分。也就是说,它作为数据类型
为 xsd:string 的字面量,是生成 UUID、转换为数据类型为
xsd:string 的字面量并移除起始
urn:uuid: 之后的结果。
STRUUID() |
"73cd4307-8a99-4691-a608-b5bda64fb6c1" |
某些函数(例如 REGEX、STRLEN、CONTAINS) 以字符串字面量作为参数。 字符串字面量是以下之一:
xsd:string 的字面量rdf:langString 且带有
语言标签的字面量
rdf:dirLangString 且同时带有
语言标签
和 基方向的字面量
使用任何其他 RDF 项都会导致对该函数的调用引发错误。
"abc" 是
简单字面量
的语法缩写,表示 "abc"^^xsd:string。
函数 SUBSTR、 STRBEFORE、 STRAFTER 和 REPLACE 返回与其第一个参数 同种类的字符串字面量。
函数 CONCAT 根据参数的 字符串字面量形式返回一个字符串 字面量。
函数 STRSTARTS、 STRENDS、 CONTAINS、 STRBEFORE 和 STRAFTER 接受两个参数。这些参数必须参数兼容; 否则,调用该函数会引发错误。
如果满足以下条件,则两个字符串字面量参数是 参数 兼容的:
xsd:string 的字面量
rdf:langString 的字面量,
并具有相同的语言标签
rdf:dirLangString 的字面量,
并具有相同的
语言标签
和相同的基方向
rdf:langString 的字面量,
第二个参数是数据类型为 xsd:string 的字面量
rdf:dirLangString 的字面量,
第二个参数具有数据类型 xsd:string
| Argument1 | Argument2 | 兼容? |
|---|---|---|
| "abc" | "b" | 是 |
| "abc"@en | "b" | 是 |
| "abc"@en | "b"@en | 是 |
| "abc"@fr | "b"@ja | 否 |
| "abc" | "b"@ja | 否 |
| "abc" | "b"@en--ltr | 否 |
| "abc"@en--ltr | "b"@en--ltr | 是 |
| "abc"@en--ltr | "b"@en | 否 |
| "abc"@en--ltr | "z" | 是 |
xsd:integer STRLEN(string literal str)
strlen 函数对应于 XPath
fn:string-length
函数,并返回一个
xsd:integer,其值等于该字面量
词汇形式的字符长度。
strlen("chat") |
4 |
strlen("chat"@en) |
4 |
strlen("chat"@en--ltr) |
4 |
strlen("chat"^^xsd:string) |
4 |
string literal SUBSTR(string literal source, xsd:integer startingLoc) string literal SUBSTR(string literal source, xsd:integer startingLoc, xsd:integer length)
substr 函数对应于 XPath
fn:substring 函数,并返回一个与
source 输入参数同种类的字面量
(数据类型为 xsd:string 的字面量、带有相同语言标签的字面量、
带有相同语言标签和基方向的字面量),但其
词汇形式
派生自源的词汇形式的子字符串。
参数 startingLoc 和 length 可以是
xsd:integer 的派生类型。
字符串中第一个字符的索引是 1。
substr("foobar", 4) |
"bar" |
substr("foobar"@en, 4) |
"bar"@en |
substr("foobar"^^xsd:string, 4) |
"bar"^^xsd:string |
substr("foobar", 4, 1) |
"b" |
substr("foobar"@en, 4, 1) |
"b"@en |
substr("foobar"^^xsd:string, 4, 1) |
"b"^^xsd:string |
string literal UCASE(string literal str)
UCASE 函数对应于 XPath
fn:upper-case
函数。它返回一个字符串字面量,
其词汇形式是参数词汇形式的大写形式。
ucase("foo") |
"FOO" |
ucase("Foo"@en) |
"FOO"@en |
ucase("foo"@en--ltr) |
"FOO"@en--ltr |
ucase("foo"^^xsd:string) |
"FOO"^^xsd:string |
string literal LCASE(string literal str)
LCASE 函数对应于 XPath
fn:lower-case 函数。
它返回一个字符串字面量,其词汇形式是参数词汇形式的小写形式。
lcase("BAR") |
"bar" |
lcase("Bar"@en) |
"bar"@en |
lcase("BAR"@en--ltr) |
"bar"@en--ltr |
lcase("BAR"^^xsd:string) |
"bar"^^xsd:string |
xsd:boolean STRSTARTS(string literal arg1, string literal arg2)
STRSTARTS 函数对应于 XPath fn:starts-with 函数。
参数必须参数兼容,
否则会引发错误。
对于这样的输入对,如果 arg1 的词汇形式
以 arg2 的词汇形式开头,则函数返回 true;否则返回
false。
strStarts("foobar", "foo") |
true |
strStarts("foobar", "abc") |
false |
strStarts("foobar"@en, "foo"@en) |
true |
strStarts("foobar"^^xsd:string, "foo"^^xsd:string) |
true |
strStarts("foobar"^^xsd:string, "foo") |
true |
strStarts("foobar", "foo"^^xsd:string) |
true |
strStarts("foobar"@en, "foo") |
true |
strStarts("foobar"@en, "foo"^^xsd:string) |
true |
strStarts("foobar", "foo"@en) |
error |
xsd:boolean STRENDS(string literal arg1, string literal arg2)
STRENDS 函数对应于 XPath fn:ends-with 函数。
参数必须参数兼容,
否则会引发错误。
对于这样的输入对,如果 arg1 的词汇形式
以 arg2 的词汇形式结尾,则函数返回 true;否则返回
false。
strEnds("foobar", "bar") |
true |
strEnds("foobar", "abc") |
false |
strEnds("foobar"@en, "bar"@en) |
true |
strEnds("foobar"^^xsd:string, "bar"^^xsd:string) |
true |
strEnds("foobar"^^xsd:string, "bar") |
true |
strEnds("foobar", "bar"^^xsd:string) |
true |
strEnds("foobar"@en, "bar") |
true |
strEnds("foobar"@en, "bar"^^xsd:string) |
true |
strEnds("foobar"@en, "bar"@en) |
error |
xsd:boolean CONTAINS(string literal arg1, string literal arg2)
CONTAINS 函数对应于 XPath fn:contains。
参数必须参数兼容,
否则会引发错误。
contains("foobar", "bar") |
true |
contains("foobar"@en, "foo"@en) |
true |
contains("foobar"^^xsd:string, "bar"^^xsd:string) |
true |
contains("foobar"^^xsd:string, "foo") |
true |
contains("foobar", "bar"^^xsd:string) |
true |
contains("foobar"@en, "foo") |
true |
contains("foobar"@en, "bar"^^xsd:string) |
true |
contains("foobar", "bar"@en) |
error |
literal STRBEFORE(string literal arg1, string literal arg2)
STRBEFORE 函数对应于 XPath fn:substring-before 函数。
参数必须参数兼容,
否则会引发错误。
对于兼容参数,如果第二个参数的词汇部分作为子字符串出现在
第一个参数的词汇部分中,则该函数返回一个与第一个参数
arg1 同种类的字面量(数据类型为
xsd:string 的字面量、带有相同语言标签的字面量)。
结果的词汇形式是 arg1 的词汇形式中,
位于 arg2 词汇形式第一次出现之前的子字符串。
如果 arg2 的词汇形式为空字符串,则认为这是匹配,
结果的词汇形式为空字符串。
如果没有这样的出现,则返回一个数据类型为 xsd:string 的
空字面量。
strBefore("abc","b") |
"a" |
strBefore("abc"@en,"bc") |
"a"@en |
strBefore("abc"@en,"b"@cy) |
error |
strBefore("abc"^^xsd:string,"") |
""^^xsd:string |
strBefore("abc","xyz") |
"" |
strBefore("abc"@en, "z"@en) |
"" |
strBefore("abc"@en, "z") |
"" |
strBefore("abc"@en, ""@en) |
""@en |
strBefore("abc"@en, "") |
""@en |
literal STRAFTER(string literal arg1, string literal arg2)
STRAFTER 函数对应于 XPath fn:substring-after 函数。
参数必须参数兼容,
否则会引发错误。
对于兼容参数,如果第二个参数的词汇部分作为子字符串出现在
第一个参数的词汇部分中,则该函数返回一个与第一个参数
arg1 同种类的字面量(数据类型为
xsd:string 的字面量、带有相同语言标签的字面量)。
结果的词汇形式是 arg1 的词汇形式中,
位于 arg2 词汇形式第一次出现之后的子字符串。
如果 arg2 的词汇形式为空字符串,则认为这是匹配,
结果的词汇形式为 arg1 的词汇形式。
如果没有这样的出现,则返回一个数据类型为 xsd:string 的
空字面量。
strAfter("abc","b") |
`"c" |
strAfter("abc"@en,"ab") |
"c"@en |
strAfter("abc"@en,"b"@cy) |
error |
strAfter("abc"^^xsd:string,"") |
"abc"^^xsd:string |
strAfter("abc","xyz") |
"" |
strAfter("abc"@en, "z"@en) |
"" |
strAfter("abc"@en, "z") |
"" |
strAfter("abc"@en, ""@en) |
"abc"@en |
strAfter("abc"@en, "") |
"abc"@en |
string literal CONCAT(string literal, ..., string literal)
CONCAT 函数接受零个或多个参数。
参数必须是字符串字面量,否则会
引发错误。
如果给出零个参数,则结果是数据类型为 xsd:string 的空字符串。
如果给出一个参数,则结果是该参数值。
如果给出两个或更多参数,则该函数返回一个 字符串字面量,使得所得 词汇形式 通过使用 fn:concat 函数连接该函数参数的 词汇形式而得到。
rdf:dirLangString、共同语言标签和基方向的字面量。
rdf:langString 和共同语言标签的字面量。
xsd:string 的字符串字面量。
concat("foo", "bar") |
"foobar" |
concat("foo"@en, "bar"@en) |
"foobar"@en |
concat("foo", "bar") |
"foobar" |
concat("foo"@en, "bar") |
"foobar" |
concat("foo"@en, "bar"@es) |
"foobar" |
concat("abc") |
"abc" |
concat("abc"@en) |
"abc"@en |
concat() |
"" |
xsd:boolean langMatches (xsd:string language-tag, xsd:string language-range)
如果参数 language-tag
(一个语言标签)
按照 [RFC4647] 第 3.3.1 节中定义的基本过滤方案,
匹配参数 language-range
(按照 [RFC4647] 第 2.1 节 语言
标签匹配的
基本语言范围),
则返回 true。否则,该函数返回 false。
如果 language-tag、language-range 或二者为空
(因而分别不是有效的语言标签或语言范围),
则该函数返回 false。
language-range 为 "*" 时匹配任何非空的 language-tag 字符串。
PREFIX dc: <http://purl.org/dc/elements/1.1/> _:a dc:title "That Seventies Show"@en . _:a dc:title "Cette Série des Années Soixante-dix"@fr . _:a dc:title "Cette Série des Années Septante"@fr-BE . _:b dc:title "Il Buono, il Bruto, il Cattivo" .
此查询使用 langMatches 和
lang 来查找英文名为
"That Seventies Show" 的节目的法语标题:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
?x dc:title "That Seventies Show"@en ;
dc:title ?title .
FILTER langMatches( lang(?title), "FR" )
}
查询结果:
| title |
|---|
| "Cette Série des Années Soixante-dix"@fr |
| "Cette Série des Années Septante"@fr-BE |
惯用形式 langMatches( lang( ?v ), "*" ) 不会匹配
没有语言标签的字面量,因为 lang( ?v ) 会返回空字符串,因此
PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
?x dc:title ?title .
FILTER langMatches( lang(?title), "*" )
}
会报告所有带有语言标签的标题:
| title |
|---|
| "That Seventies Show"@en |
| "Cette Série des Années Soixante-dix"@fr |
| "Cette Série des Années Septante"@fr-BE |
xsd:boolean REGEX (string literal text, xsd:string pattern) xsd:boolean REGEX (string literal text, xsd:string pattern, xsd:string flags)
调用 XPath fn:matches 函数,以将
text 与正则表达式 pattern 进行匹配。正则
表达式语言定义于 XQuery 1.0 and XPath 2.0 Functions and Operators
第 7.6.1 正则
表达式语法节
[XPATH-FUNCTIONS-31]。
PREFIX foaf: <http://xmlns.com/foaf/0.1/> _:a foaf:name "Alice". _:b foaf:name "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE {
?x foaf:name ?name
FILTER regex(?name, "^ali", "i")
}
查询结果:
| name |
|---|
| "Alice" |
string literal REPLACE (string literal arg, xsd:string pattern, xsd:string replacement ) string literal REPLACE (string literal arg, xsd:string pattern, xsd:string replacement, xsd:string flags)
REPLACE 函数对应于 XPath fn:replace 函数。它把正则表达式
pattern 的每个非重叠出现替换为替换字符串。
正则表达式匹配可能涉及修饰符标志。见 REGEX。
| replace("abcd", "b", "Z") | "aZcd" |
| replace("abab", "B", "Z","i") | "aZaZ" |
| replace("abab", "B.", "Z","i") | "aZb" |
xsd:string ENCODE_FOR_URI(string literal ltrl)
ENCODE_FOR_URI 函数对应于 XPath fn:encode-for-uri 函数。它返回一个
数据类型为 xsd:string 的字面量,其词汇形式是根据
fn:encode-for-uri
函数转换保留字符后,从输入的词汇形式得到的。
encode_for_uri("Los Angeles") |
"Los%20Angeles" |
encode_for_uri("Los Angeles"@en) |
"Los%20Angeles" |
encode_for_uri("Los Angeles"^^xsd:string) |
"Los%20Angeles" |
numeric ABS (numeric term)
返回 arg 的绝对值。如果 arg
不是数值,则引发错误。
对于具有来自 XDM 的数据类型的项, 此函数与 fn:abs 相同。
ABS(1) |
1 |
ABS(-1.5) |
1.5 |
numeric ROUND (numeric term)
返回最接近该参数且不含小数部分的数字。如果有两个这样的数字,
则返回最接近正无穷的那个。如果 arg 不是数值,
则引发错误。
对于具有来自 XDM 的数据类型的项,此函数与 fn:round 相同。
ROUND(2.4999) |
2.0 |
ROUND(2.5) |
3.0 |
ROUND(-2.5) |
-2.0 |
numeric CEIL (numeric term)
返回不小于 arg 值且没有小数部分的最小
(最接近负无穷的)数字。如果 arg
不是数值,则引发错误。
对于具有来自 XDM 的数据类型的项, 此函数与 fn:ceiling 相同。
CEIL(10.5) |
11.0 |
CEIL(-10.5) |
-10.0 |
numeric FLOOR (numeric term)
返回不大于 arg 值且没有小数部分的最大
(最接近正无穷的)数字。如果 arg
不是数值,则引发错误。
对于具有来自 XDM 的数据类型的项, 此函数与 fn:floor 相同。
FLOOR(10.5) |
10.0 |
FLOOR(-10.5) |
-11.0 |
xsd:double RAND ( )
返回一个介于 0(含)和 1.0e0(不含)之间的伪随机数。 每次调用此函数都可能产生不同的数字。数字应以近似相等的概率产生。
rand() |
"0.31221030831984886"^^xsd:double |
xsd:dateTime NOW ()
返回当前查询执行的 XSD dateTime 值。在任一次查询执行中, 对此函数的所有调用都必须返回相同的值。返回的确切时刻未指定。
NOW() |
"2011-01-10T14:45:13.815-05:00"^^xsd:dateTime |
xsd:integer YEAR (xsd:dateTime arg)
以整数形式返回 arg 的年份部分。
此函数对应于 fn:year-from-dateTime。
YEAR("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
2011 |
xsd:integer MONTH (xsd:dateTime arg)
以整数形式返回 arg 的月份部分。
此函数对应于 fn:month-from-dateTime。
MONTH("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
1 |
xsd:integer DAY (xsd:dateTime arg)
以整数形式返回 arg 的日部分。
此函数对应于 fn:day-from-dateTime。
day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
10 |
xsd:integer HOURS (xsd:dateTime arg)
以整数形式返回 arg 的小时部分。该值与
XSD dateTime 的词汇形式中给出的值一致。
此函数对应于 fn:hours-from-dateTime。
HOURS("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
14 |
xsd:integer MINUTES (xsd:dateTime arg)
返回 arg 词汇形式中的分钟部分。该值与
XSD dateTime 的词汇形式中给出的值一致。
此函数对应于 fn:minutes-from-dateTime。
MINUTES("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
45 |
xsd:decimal SECONDS (xsd:dateTime arg)
返回 arg 词汇形式中的秒部分。
此函数对应于 fn:seconds-from-dateTime。
SECONDS("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
13.815 |
xsd:dayTimeDuration TIMEZONE (xsd:dateTime arg)
以 xsd:dayTimeDuration 形式返回 arg 的时区部分。
如果没有时区,则引发错误。
此函数对应于 fn:timezone-from-dateTime, 但对没有时区的字面量的处理除外。
TIMEZONE("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
"-PT5H"^^xsd:dayTimeDuration |
TIMEZONE("2011-01-10T14:45:13.815Z"^^xsd:dateTime) |
"PT0S"^^xsd:dayTimeDuration |
TIMEZONE("2011-01-10T14:45:13.815"^^xsd:dateTime) |
error |
xsd:string TZ (xsd:dateTime arg)
以数据类型为 xsd:string 的字面量形式返回
arg 的时区部分。
如果没有时区,则返回空字符串。
TZ("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) |
"-05:00" |
TZ("2011-01-10T14:45:13.815Z"^^xsd:dateTime) |
"Z" |
TZ("2011-01-10T14:45:13.815"^^xsd:dateTime) |
"" |
triple term TRIPLE (RDF term subj, RDF term pred, RDF term obj)
<<( subj pred obj )>>
如果三元组组(subj、
pred、
obj)
是一个 RDF 三元组
(也就是说,subj 是
IRI 或
blank node;
pred 是
IRI;
并且 obj 是
IRI、
triple term、
blank node 或
literal),
则该函数返回一个具有这三个元素的三元组项。
否则,该函数引发错误。
作为简写记法,TRIPLE 函数
也可以使用 <<( 和 )>>,
以三元组项表达式的形式书写。
这种简写形式有语法限制:
函数形式 TRIPLE 可以与任意表达式一起使用。
VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?s ?date {
?s ?p ?o .
BIND( <<( ?s ?p ?o )>> AS ?tt )
:myreifier rdf:reifies ?tt .
:myreifier :tripleAdded ?date .
}
VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?s ?date {
?s ?p ?o .
BIND( TRIPLE(?s, ?p, ?o) AS ?tt )
:myreifier rdf:reifies ?tt .
:myreifier :tripleAdded ?date .
}
RDF term SUBJECT (triple term triple-term)
如果参数是一个 triple term, 该函数返回该三元组项的 subject。 如果参数不是 triple term, 则引发错误。
RDF term PREDICATE (triple term triple-term)
如果参数是一个 triple term, 该函数返回该三元组项的 predicate。 如果参数不是 triple term, 则引发错误。
RDF term OBJECT (triple term triple-term)
如果参数是一个 triple term, 该函数返回该三元组项的 object。 如果参数不是 triple term, 则引发错误。
xsd:boolean isTRIPLE (RDF term term)
如果参数是一个triple term, 该函数返回 true。 如果参数是任何其他种类的 RDF 项, 该函数返回 false。
xsd:string MD5 (xsd:string arg)
返回根据 xsd:string 的词汇形式计算出的 MD5 校验和,
表示为十六进制数字字符串。十六进制数字应该为小写。
MD5("abc") |
"900150983cd24fb0d6963f7d28e17f72" |
xsd:string SHA1 (xsd:string arg)
返回根据 xsd:string 的词汇形式计算出的 SHA1 校验和,
表示为十六进制数字字符串。十六进制数字应该为小写。
SHA1("abc") |
"a9993e364706816aba3e25717850c26c9cd0d89d" |
xsd:string SHA256 (xsd:string arg)
返回根据 xsd:string 的词汇形式计算出的 SHA256 校验和,
表示为十六进制数字字符串。十六进制数字应该为小写。
SHA256("abc") |
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
xsd:string SHA384 (xsd:string arg)
返回根据 xsd:string 的词汇形式计算出的 SHA384 校验和,
表示为十六进制数字字符串。十六进制数字应该为小写。
SHA384("abc") |
"cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"
|
xsd:string SHA512 (xsd:string arg)
返回根据 xsd:string 的词汇形式计算出的 SHA512 校验和,
表示为十六进制数字字符串。十六进制数字应该为小写。
SHA512("abc") |
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
|
SPARQL 导入了 XPath 和 XQuery 函数与运算符 3.1 [XPATH-FUNCTIONS-31] 第 19.1 从 原始类型到原始类型的转换中定义的一部分 XPath 构造器函数。 SPARQL 构造器包括适用于 SPARQL 操作数数据类型的所有 XPath 构造器,以及 RDF 数据模型所施加的 附加数据类型。 SPARQL 中的转换通过在源类型操作数上调用目标类型的构造器函数来执行。
XPath 只定义了从一种 XML Schema 数据类型到另一种数据类型的转换。其余转换 定义如下:
xsd:string 会产生一个
字面量,其词汇值为组成该 IRI 的码位,
且数据类型为 xsd:string。
下表概述始终允许(Y)、
从不允许(N)以及依赖于词汇
值(M)的转换操作。例如,从
xsd:string(第一行)到 xsd:float(第二列)的转换操作
依赖于词汇值(M)。
bool = xsd:boolean
dbl = xsd:double
flt = xsd:float
dec = xsd:decimal
int = xsd:integer
dT = xsd:dateTime
str = xsd:string
IRI = IRI
| From \ To | str | flt | dbl | dec | int | dT | bool |
|---|---|---|---|---|---|---|---|
| str | Y | M | M | M | M | M | M |
| flt | Y | Y | Y | M | M | N | Y |
| dbl | Y | Y | Y | M | M | N | Y |
| dec | Y | Y | Y | Y | Y | N | Y |
| int | Y | Y | Y | Y | Y | N | Y |
| dT | Y | N | N | N | N | Y | N |
| bool | Y | Y | Y | Y | Y | N | Y |
| IRI | Y | N | N | N | N | N | N |
应注意,任何被指定为在某些条件下返回错误的函数或运算符, 都是有效的扩展点。也就是说,实现可以在这些错误情形中返回 非错误值,并且仍然符合本推荐标准。
PrimaryExpression 文法规则可以是对由 IRI 命名的扩展函数的调用。扩展函数接受若干 RDF 项作为参数,并返回一个 RDF 项。 这些函数的语义由标识该函数的 IRI 标识。
使用扩展函数的 SPARQL 查询可能具有有限的互操作性。
例如,考虑一个名为 func:even 的函数:
xsd:booleanfunc:even(numericvalue)
此函数可在 FILTER 中按如下方式调用:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX func: <http://example.org/functions#>
SELECT ?name ?id
WHERE {
?x foaf:name ?name ;
func:empId ?id .
FILTER (func:even(?id))
}
再举第二个例子,考虑一个计算两点之间距离的函数
aGeo:distance,此处用它查找 Grenoble 附近的地点:
xsd:doubleaGeo:distance(numericx1,numericy1,numericx2,numericy2)
PREFIX aGeo: <http://example.org/geo#>
SELECT ?neighbor
WHERE {
?a aGeo:placeName "Grenoble" .
?a aGeo:locationX ?axLoc .
?a aGeo:locationY ?ayLoc .
?b aGeo:placeName ?neighbor .
?b aGeo:locationX ?bxLoc .
?b aGeo:locationY ?byLoc .
FILTER ( aGeo:distance(?axLoc, ?ayLoc, ?bxLoc, ?byLoc) < 10 ) .
}
扩展函数可能用于测试核心 SPARQL 规范不支持的某种应用数据类型; 它也可能是在数据类型格式之间进行转换,例如从另一种日期格式 转换为 XSD dateTime RDF 项。
本节定义在给定查询字符串和 RDF 数据集的情况下,对图模式和解 修饰符求值的正确行为。它并不意味着 SPARQL 实现 必须使用这里定义的过程。
执行 SPARQL 查询的结果由一系列步骤定义,从作为字符串的 SPARQL 查询开始,将该字符串转为抽象语法形式,然后将 抽象语法转为由 SPARQL 代数中的运算符构成的 SPARQL 抽象查询。随后在 RDF 数据集上 对该抽象查询求值。
RDF 数据集的概念定义于 [RDF12-CONCEPTS]。
对于以下定义,我们将每个 RDF 数据集捕获为一个集合:
{ G, (<u1>, G1), (<u2>, G2), ... (<un>, Gn) } 其中 G 和每个 Gi 都是图,并且每个 <ui> 是 IRI 或空白 节点。每个 <ui> 都彼此不同。
G 称为默认图。(<ui>, Gi) 称为命名 图。
定义:活动图
活动图是数据集中用于基本图模式 匹配的图。
定义:查询变量
我们假定有一个可数无限集合 V,它与所有 RDF 项的集合不相交。 该集合 V 的每个成员都是一个 查询变量。
定义:三元组模式
三元组模式是一个 3 元组, 它按如下方式归纳定义: 如果
则 (s, p, o) 是一个三元组模式。
三元组模式不允许循环 (即,一个三元组模式不能包含其自身)。
该三元组模式定义包含字面量主语。 RDF-core 已注意到这一点。
“[RDF core 工作组]注意到,它不知道有什么理由不允许字面量作为 主语,并且未来具有较少限制性章程的 WG 可能 扩展语法以允许字面量作为语句的主语。”
由于 RDF 图不能包含字面量主语,任何以字面量作为主语的 SPARQL 三元组模式都无法在任何 RDF 图上匹配。
定义:基本图模式
基本图模式是 三元组模式的集合。
空图模式是一个为空集合的基本图模式。
定义:属性路径
属性路径是三元组序列 ST 中的三元组 ti 的序列,其中 n = length(ST)-1,使得对于 i=0 到 n,ti 的宾语与 ti+1 的主语为同一项。
我们称 t0 的主语为路径的起点。
我们称 tn 的宾语为路径的终点。
如果每个 ti 都是 G 的三元组,则属性路径是图 G 中的一条路径。
属性路径不会跨越一个数据集中的多个图。
定义:属性路径表达式
属性路径表达式是使用上文所述属性路径形式的表达式。
定义:属性路径模式
属性路径模式是一个 3 元组 (s, p, o),其中:
属性路径模式是三元组 模式的泛化,用于在谓语位置包含属性路径表达式。
解映射是从一组变量到一组 RDF 项的映射。在含义清楚时,我们使用 “解”这个术语。
定义:解序列
解序列是解的列表,可能是无序的。
写作 expr(μ) 表示表达式 expr 的值,该值使用 μ 给出的变量项。求值可能产生错误。
定义:SPARQL 查询
SPARQL 抽象查询是一个元组 (E, DS, QF), 其中:
定义:查询层级
查询层级是图模式、一组分组和聚合,以及一组 解修饰符。
查询是一棵“查询层级”的树,其中每个子查询 在该树中形成一个查询层级。
为了定义 SPARQL 查询的求值语义, 首先将 SPARQL 查询字符串的抽象语法树 (由 SPARQL 文法定义) 转换为一种类似于 SPARQL 代数的语法。 本节定义可以在该代数语法中形成的表达式, 然后在第 18.3 转换到代数语法中定义 SPARQL 查询字符串到该代数语法的转换。
代数查询表达式 按如下方式递归定义:
如前一定义所使用的 代数属性路径表达式概念, 按如下方式递归定义:
本节定义将 SPARQL 查询字符串中的图模式和解修饰符转换为
代数
查询表达式的过程。所描述的过程转换一个
查询嵌套层级,该层级由使用嵌套 SELECT 语法的子查询形成,
并递归应用于子查询。每个层级由图模式匹配和
过滤组成,随后应用解修饰符。
解析 SPARQL 查询字符串,并应用第 4. SPARQL 语法中给出的 IRI 和三元组模式缩写。 此时,抽象语法树由以下内容组成:
| 模式 | 修饰符 | 查询形式 | 其他 |
|---|---|---|---|
| RDF 项 | DISTINCT | SELECT | VALUES |
| 属性路径表达式 | REDUCED | CONSTRUCT | SERVICE |
| 属性路径模式 | 投影 | DESCRIBE | |
| 组 | ORDER BY | ASK | |
| OPTIONAL | LIMIT | ||
| UNION | OFFSET | ||
| GRAPH | Select 表达式 | ||
| BIND | |||
| GROUP BY | |||
| HAVING | |||
| MINUS | |||
| FILTER |
如果在查询的 代数表达式求值过程中的某一点, 存在某种方式使变量处于解映射的定义域中,则我们定义该变量为 在作用域内。下面的定义提供了一种从查询的 抽象语法树确定这一点的方法。
请注意,带有投影的子查询可以隐藏变量;在
FILTER 或 MINUS 中使用变量不会使该变量在这些形式之外
处于作用域内。
令 P、P1 和 P2 为图模式,并令 E、
E1,..., 到 En 为表达式。变量 v 在作用域内,如果:
| 语法形式 | 作用域内变量 |
|---|---|
| 基本图模式(BGP) | v 出现在 BGP 中 |
| 路径 | v 出现在路径中 |
GroupGraphPattern { P1 P2 ... } |
如果 v 在 P1、P2、... 中的一个或多个内处于作用域内,则 v 在作用域内 |
GRAPH X { P } |
X 是变量 v,或 v 在 P 中处于作用域内 |
{ P1 } UNION { P2 } |
v 在 P1 中处于作用域内或在 P2 中处于作用域内 |
OPTIONAL {P} |
v 在 P 中处于作用域内 |
SERVICE X {P} |
X 是变量 v,或 v 在 P 中处于作用域内 |
BIND (expr AS v) |
v 在作用域内 |
SELECT .. v .. { P } |
v 在作用域内 |
SELECT ... (expr AS v) |
v 在作用域内 |
GROUP BY ... v |
v 在作用域内 |
GROUP BY ... (expr AS v) |
v 在作用域内 |
SELECT * { P } |
v 在 P 中处于作用域内 |
VALUES v { values } |
v 在作用域内 |
VALUES varlist { values } |
如果 v 在 varlist 中,则 v 在作用域内 |
变量 v 在 (expr AS v) 形式的位置上
不得处于作用域内。(expr AS v) 的作用域会立即应用于
SELECT 表达式。
BIND (expr AS v) 要求变量 v 不得从
使用它的组图模式中的前序元素处于作用域内。
在 SELECT 中,变量 v 不得在
SELECT 子句的图模式中处于作用域内,也不得在该子句中更早的另一个 select 表达式中使用。
本节描述将 SPARQL 图模式转换为
代数查询表达式的过程。该
过程应用于构成查询 WHERE 子句的组图模式
(大括号(“{ }”)定界符之间的单元),
并递归应用于组图模式中的每个语法元素。
转换结果是一个代数查询表达式。
概括来说,步骤按如下方式应用:
FILTER
我们写作
translate(graph pattern)
表示这里描述的用于转换图模式的算法。
OPTIONAL { { ... FILTER ( ... ?x ... ) } }..
这由两个非规范性测试用例说明:
在所有图模式转换之后应用简化步骤是 首选解读。
展开第 4. SPARQL 语法中给出的 IRI 和三元组模式缩写。
FILTER 表达式应用于其出现所在的整个组图模式。
执行过滤的代数运算符会在每个组元素转换之后添加到组中。
我们在此将过滤器收集到一起并将它们从组中移除,然后
将它们应用于整个已转换的组
图模式。
Let FS := empty set
For each form FILTER(expr) in the group graph pattern
FS := FS ∪ {expr}
End
过滤表达式集合 FS 将在稍后使用。
下表给出了 SPARQL 查询字符串中 属性路径表达式到 代数属性路径表达式的转换。 这会递归应用于属性路径表达式的所有元素。
此步骤之后的下一步会将
某些形式转换为三元组模式,随后这些三元组模式会通过相邻性
(没有中间的组模式定界符
{ 和 }) 或
其他语法形式)转换为基本图模式。总体而言,SPARQL 语法中仅由 IRI 组成的属性路径会成为三元组
模式,并被聚合到基本图模式中。
注:
| 语法形式(path) | 代数形式(path) |
|---|---|
iri |
Link(iri) |
^path |
Inv(path) |
!(:iri1|...|:irin) |
NPS({:iri1 ... :irin})
|
!(^:iri1|...|^:irin) |
Inv( NPS({:iri1 ... :irin}) )
|
!(:iri1|...|:irii|^:irii+1|...|^:irim)
|
Alt( NPS({:iri1 ...:irii}), |
path1 / path2 |
Seq(path1, path2) |
path1 | path2 |
Alt(path1, path2) |
path* |
ZeroOrMorePath(path)
|
path+ |
OneOrMorePath(path)
|
path? |
ZeroOrOnePath(path)
|
前一步转换了属性路径表达式。 此步骤转换属性路径模式, 后者由一个主语端点、一个属性路径表达式和一个宾语 端点组成。 此步骤假定属性路径模式的属性路径表达式 已经以 代数属性路径表达式形式给出。 此步骤的结果可能是三元组模式,以及 形式为 Path(...) 的 代数查询表达式。
注:
| 代数形式(path) | 转换 |
|---|---|
| x Link(iri) y | x iri y |
| x Inv(iri) y | y iri x |
| x Seq(ppe1, ppe2) y | x ppe1 var . var ppe2 y |
| x ppe y | Path(x, ppe, y) |
整个路径转换过程的示例(?_V 是一个新
变量):
在转换属性路径之后,任何相邻的三元组模式都会被收集到一起
以形成基本图模式 BGP(triples)。
接下来,我们转换每个剩余的图模式形式,递归应用 转换过程。
如果形式是
GroupOrUnionGraphPattern
Let A := undefined
For each element G in the GroupOrUnionGraphPattern
If A is undefined
A := Translate(G)
Else
A := Union(A, Translate(G))
End
The result is A
如果形式是
GraphGraphPattern
If the form is GRAPH IRI GroupGraphPattern
The result is Graph(IRI, Translate(GroupGraphPattern))
If the form is GRAPH Var GroupGraphPattern
The result is Graph(Var, Translate(GroupGraphPattern))
如果形式是
GroupGraphPattern:
Let G := ContextSolution
For each element E in the sequence of elements in the GroupGraphPattern
If E is of the form OPTIONAL{P}
Let A := Translate(P)
If A is of the form Filter(F, A2)
G := LeftJoin(G, A2, F)
Else
G := LeftJoin(G, A, true)
End
End
If E is of the form MINUS{P}
G := Minus(G, Translate(P))
End
If E is of the form BIND(expr AS var)
G := Extend(G, var, expr)
End
If E is any other form
Let A := Translate(E)
G := Join(G, A)
End
End
The result is G.
如果形式是 InlineData
The result is a multiset data of solution mappings.
data 通过从变量列表(或单个变量)中对应位置的变量形成解映射而形成;
如果 DataBlockValue
是单词 UNDEF,则省略一个绑定。
如果形式是 SubSelect
The result is ToMultiset(Translate(SubSelect))
在组完成转换之后,会添加过滤表达式,使其将应用于组中其余部分的整体:
If FS is not empty
Let G := output of preceding step
Let X := Conjunction of expressions in FS
G := Filter(X, G)
End
某些只包含一个图模式的组会变成 Join(Z, A),其中 Z 是空基本 图 模式(即空集合)。这些会被替换为 A。空 图模式 Z 是 join 的单位元:
Replace Join(Z, A) by A Replace Join(A, Z) by A
重写示例的第二种形式,是第一种形式经简化步骤移除空组 join 后的结果。 Z 是空基本图模式。
示例:包含由单个三元组模式组成的基本图模式的组:
示例:包含由两个三元组模式组成的基本图模式的组:
示例:由两个基本图模式的 union 组成的组:
示例:由一个 union 和一个基本图模式的 union 组成的组:
示例:由一个基本图模式和一个 optional 图模式组成的组:
示例:由一个基本图模式和两个 optional 图模式组成的组:
示例:由一个基本图模式和一个带有 filter 的 optional 图模式组成的组:
示例:由一个 union 图模式和一个 optional 图模式组成的组:
示例:由一个基本图模式、一个 filter 和一个 optional 图 模式组成的组:
示例:涉及 BIND 的模式:
示例:涉及 BIND,且带有 简化步骤的模式:
{} 表示空 BGP,而上面的前几个示例则改用
Z。这些示例在这方面应该保持一致。
示例:涉及 MINUS 的模式:
示例:涉及子查询的模式:
在此步骤中,我们按以下顺序处理查询层级上的子句:
步骤:GROUP BY
如果使用了 GROUP BY 关键字,或者由于在
HAVING 或 ORDER BY 子句中,或在
投影中使用聚合而存在隐式分组,则通过 Group 函数执行分组。
在这种情况下,在分组之前,通过应用 ToList 函数
将解集转换为解序列。
接下来,Group 函数
将此解序列划分为由一个或
多个解组成的组,并具有相同的总体基数。对于隐式分组,使用一个固定
常量 (1) 将所有解分到单个组中。
步骤:聚合
聚合步骤作为查询层级上的转换应用,将 查询层级中的聚合表达式替换为 Aggregation() 代数 表达式。
使用任何聚合的查询层级的转换如下给出:
Let A := the empty sequence
Let Q := the query level being evaluated
Let P := algebraic query expression produced for the GroupGraphPattern of the query level
Let E := [], a list of pairs of the form (variable, expression)
If Q contains GROUP BY exprlist
Let Grp := Group(exprlist, ToList(P))
Else If Q contains an aggregate in SELECT, HAVING, ORDER BY
Let Grp := Group((1), ToList(P))
Else
skip the rest of the Aggregates step
End
Global i := 1 # Initially 1 for each query processed
For each (X AS Var) in SELECT, each HAVING(X), and each ORDER BY X in Q
For each unaggregated variable V in X
Replace V with SAMPLE(V)
End
For each aggregate R(args ; scalarvals) now in X
# note: scalarvals may be omitted; if so, it is equivalent to the empty function
Ai := Aggregation(args, R, scalarvals, Grp)
Replace R(...) with aggi in Q
i := i + 1
End
End
For each variable V appearing outside of an aggregate
Ai := Aggregation(V, Sample, {}, Grp)
E := E append (V, aggi)
i := i + 1
End
A := Ai, ..., Ai-1
P := AggregateJoin(A)
列表 E 将在第 18.3.4.4 SELECT 表达式中转换 SELECT 表达式时使用。
HAVING 表达式使用与 FILTER() 相同的规则求值。 请注意,由于 HAVING 子句求值所在的逻辑位置, SELECT 子句所投影的表达式对 HAVING 子句不可见。
Let Q := the query level being evaluated
Let P := the algebraic query expression produced for the query level so far
For each HAVING(E) in Q
P := Filter(E, P)
End
如果查询带有尾随 VALUES 子句:
Let P := the algebraic query expression produced for the query level so far P := Join(P, ToMultiset(data)) where data is a solution sequence derived from the VALUES clause
数据的转换与内联 数据相同。
步骤:Select 表达式
我们需要考虑抽象语法的两种形式:
SELECT selItem ... { pattern }
SELECT * { pattern }
Let X := algebraic query expression from earlier steps
Let VS := set of all variables visible in the pattern,
so restricted by sub-SELECT projected variables and GROUP BY variables.
Not visible: only in filter, exists/not exists, masked by a subselect,
non-projected GROUP variables, only in the right hand side of MINUS
Let PV := {}, a set of variable names
Let E := a list of pairs of the form (variable, expression), populated in Section 18.3.4.1 Grouping and Aggregation
If "SELECT *"
PV := VS
If "SELECT selItem ..."
For each selItem
If selItem is a variable
PV := PV ∪ { variable }
End
If selItem is (expr AS var)
var must not appear in VS nor in PV; if it does then generate a syntax error and stop
PV := PV ∪ { var }
E := E append (var, expr)
End
End
For each pair (var, expr) in E
X := Extend(X, var, expr)
End
Result is X
The set PV is used later for projection (see Section 18.3.5.2 Projection).
当变量被用作 AS 的命名目标(例如 ... AS ?x),且该变量在 SELECT 的 WHERE 子句内部使用,或已在此 SELECT 表达式中更早被用作 AS 的目标时,会产生语法错误。
解修饰符应用于模式匹配之后的 SPARQL 查询处理。
由于解修饰符作用于 解映射序列,因此到此为止产生的查询结果首先会从 解映射的多重集转换为这样的序列。虽然此序列没有隐含的排序, 且重复项不必相邻,但该序列 就其包含的元素及其重数而言与多重集相同。 为应用这种从多重集到序列的转换, 将解修饰符转换为 代数查询表达式 的算法从以下步骤开始,其中 A 是 前一节算法产生的 代数查询表达式。
Let M := ToList(A)
现在,按以下顺序应用解修饰符:
如果查询字符串有 ORDER BY 子句
M := OrderBy(M, 排序比较器列表)
投影变量集合 PV 已在 处理 SELECT 表达式时计算。
M := Project(M, PV)
如果查询包含 DISTINCT,
M := Distinct(M)
如果查询包含 REDUCED,
M := Reduced(M)
如果查询包含 “OFFSET offset” 和 “LIMIT limit”
M := Slice(M, offset, limit)
如果查询包含 “OFFSET offset”,但查询不包含 “LIMIT limit”
M := Slice(M, offset)
如果查询包含 “LIMIT limit”,但查询不包含 “OFFSET offset”
M := Slice(M, 0, limit)
整体代数查询表达式为 M。
在匹配图模式时,可能的解形成一个 多重集, 也称为 包。多重集是一种 无序元素集合,其中每个元素可以出现多次。它由一个元素集合和一个给出这些 元素各自重数的函数来描述(即,该元素在多重集中包含的次数)。
写作 μ 表示解映射。
写作 μ0 表示这样的映射:dom(μ0) 是 空集合。
写作 Ω0 表示只包含空映射 μ0、且重数为 1 的多重集。这是 join 单位元。
写作 μ(x) 表示把变量 x 映射到 RDF 项 t 的解映射:{ (x, t) }。
定义:兼容映射
如果对于同时位于 dom(μ1) 和 dom(μ2) 中的每个 变量 v,都有 μ1(v) = μ2(v),则两个解映射 μ1 和 μ2 兼容。
这里,μ1(v) = μ2(v) 表示 μ1(v) 和 μ2(v) 是同一 RDF 项。
如果 μ1 和 μ2 兼容,则 μ1 ∪ μ2 也是 一个映射。写作 merge(μ1, μ2) 表示 μ1 ∪ μ2
定义:重数
给定一个由解映射组成的多重集 Ω 和一个解 映射 μ,我们写作 multiplicity(μ | Ω) 来表示 μ 在 Ω 中出现的次数。
类似地,给定一个解序列 Ψ 和一个解 映射 μ,我们写作 multiplicity(μ | Ψ) 来表示 μ 在 Ψ 中出现的次数。
基本图模式会与查询该部分的活动图进行匹配。 可以通过把变量和空白节点都替换为项,来实例化基本图模式, 从而得到两种实例概念。空白节点使用从空白 节点到 RDF 项的 RDF 实例映射 σ 进行替换; 变量则由从查询变量到 RDF 项的解映射替换。
定义:模式实例映射
模式实例映射 P 是 RDF 实例映射 σ 和解映射 μ 的组合。P(x) = μ(σ(x))
对于 BGP “x”,P(x) 表示替换 x 中 σ 有定义的空白节点 b 为 σ(b),并替换 x 中 μ 有定义的所有变量 v 为 μ(v) 后所得的结果。
任何模式实例映射都会定义一个唯一的解映射和一个唯一的 RDF 实例 映射,分别通过将其限制到查询变量和空白节点而获得。
令 BGP 为一个基本图模式,令 G 为一个 RDF 图。
当存在一个模式实例映射 P,使得 P(BGP) 是 G 的子图,且 μ 是 P 限制到 BGP 中查询变量后的结果时,μ 是 BGP 从 G 得到的一个解。
multiplicity( μ | Ω ) = 不同 RDF 实例映射 σ 的数量,使得 P = μ(σ) 是一个模式实例映射,并且 P(BGP) 是 G 的子图。
如果一个基本图模式是空集合,则解为 Ω0。
此定义允许解映射把基本图模式 BGP 中的变量绑定到 G 中的空白节点。由于 SPARQL 把结果格式 文档(SPARQL 查询结果 XML 格式(第二 版)、SPARQL 1.1 查询结果 JSON 格式和 SPARQL 1.1 查询结果 CSV 和 TSV 格式)中的空白节点标识符视为以文档为作用域, 因而不能把它们理解为标识数据集活动图中的节点。如果 DS 是一个查询的数据集, 那么模式解因此被理解为不是来自 DS 本身的活动图, 而是来自一个称为作用域图的 RDF 图。这个图就是 DS 的活动图,但其中的空白节点会被统一替换为新的空白节点, 这些新空白节点既不在 DS 中,也不在 BGP 中,这与 合并 RDF 图时的做法相似。 同一个作用域图会用于单个查询的所有解。作用域图纯粹是一种理论 构造;在实践中,其效果只是通过空白节点标识符的文档作用域约定来获得。
由于 RDF 空白节点会让许多模式产生无限多的冗余解, 因此可能存在无限多个模式解(通过把空白节点替换为不同的 空白节点而获得)。因此,有必要以某种方式界定基本 图模式的解。SPARQL 使用子图匹配准则来确定基本 图模式的解。对于从基本图模式到活动图子集的每个不同模式实例映射, 都有一个解。
这针对计算的便利性而非冗余消除进行了优化。即使数据集的活动图是 精简的, 它也允许查询结果包含冗余,并允许逻辑等价的数据集 产生不同的查询结果。
本节定义属性路径 模式的求值。属性路径模式由一个主语端点(一个 RDF 项或一个变量)、 一个属性路径表达式和一个对象端点组成。
属性路径表达式的转换
会把每个属性路径表达式
转换为一个代数属性路径表达式。
例如,属性路径表达式 (:p/:q)*
是一个涉及序列属性路径的 ZeroOrMorePath 表达式,
并被转换为代数属性路径表达式
ZeroOrMorePath( Seq(Link(:p), Link(:q)) )。
随后,属性路径模式的转换 会把其中一些代数属性路径表达式 转换为其他 SPARQL 图模式,例如把长度为一的属性路径转换为三元组 模式,而这些三元组模式又会被组合为基本图模式。 剩下的则是带有以下运算符的代数属性路径表达式: Alt、 ZeroOrOnePath、 ZeroOrMorePath、 OneOrMorePath 和 NPS, 以及这些运算符中包含的代数属性路径 表达式。
带有这些剩余代数属性路径表达式的属性路径模式 会以端点 X 和 Y 的 代数语法形式 Path(X, ppe, X) 出现。
为了表示属性路径模式的求值,对于每个形式为 Path(X, ppe, Y) 的 代数查询表达式, 我们写作如下:
ppeval(X, ppe, Y)
这会产生一个解 映射多重集,每个解映射都对所使用的变量有绑定(X 和 Y 中的每一个都可以 是变量)。某些运算符只产生解映射集合。
| 写作 | 当 x 是 |
|---|---|
x:term |
一个 RDF 项 |
x:var |
一个变量 |
ppeval 的签名应该扩展为:
ppeval(X, ppe, Y, G),
其中 G 是一个 RDF 图。
所有求值都通过匹配整个查询求值中该点的活动图 来执行。为清晰起见,我们省略在每个定义中显式包含活动图。
如果 X 和 Y 都是变量,这与如下形式相同:
ppeval(X:var, Link(iri), Y:var) =
{ (X, xn:term) (Y, yn:term) | triple (xn, iri, yn) is in the active graph }
如果 X 是变量,而 Y 是 RDF 项:
ppeval(X:var, Link(iri), Y:term) =
{ (X, xn:term) | triple (xn, iri, Y) is in the active graph }
如果 X 是 RDF 项,而 Y 是变量:
ppeval(X:term, Link(iri), Y:var) =
{ (Y, yn:term) | triple (X, iri, yn) is in the active graph }
如果 X 和 Y 都是 RDF 项:
ppeval(X:term, Link(iri), Y:term)
= { μ0 } if triple (X, iri, Y) is in the active graph
= { { } } = Ω0
ppeval(X:term, Link(iri), Y:term) =
{ } if triple (X, iri, Y) is not in the active graph
非正式地说,求值谓词属性路径与在查询求值的该点执行一个
SELECT * { X iri Y }
子查询相同。
定义:序列属性路径的求值
令 ppe1 和 ppe2 为代数属性路径表达式。令 V 为一个新变量。
ppeval(X, Seq(ppe1, ppe2), Y) = ToMultiSet( Project(ToList(A), PV) )
其中 A =
Join( ppeval(X,
ppe1, V), ppeval(V,
ppe2, Y) )
且 PV = { projVar ∈ {X,Y} | projVar 是
变量 }。
非正式地说,这与如下形式相同:
SELECT * { X P1 _:a . _:a P2 Y }
其中 P1 是一个
属性路径表达式,
它可以被转换为
代数属性路径表达式
ppe1,
而 P2 可以被转换为 ppe2。
这一观察基于这样的事实:空白节点 _:a 的行为类似于一个变量(在简单
蕴涵下),只是它不会出现在 SELECT * 的结果中。
定义:替代属性路径的求值
令 ppe1 和 ppe2 为代数属性路径表达式。
ppeval(X, Alt(ppe1, ppe2), Y) = Union( ppeval(X, ppe1, Y), ppeval(X, ppe2, Y) )
非正式地说,这与如下形式相同:
SELECT * { { X P1 Y } UNION { X P2 Y } }
其中 P1 是一个 属性路径表达式, 它可以被转换为 代数属性路径表达式 ppe1, 而 P2 可以被转换为 ppe2。
定义:ZeroOrOnePath 的求值
令 ppe 为一个代数属性路径 表达式。 令 G 为活动图。
ppeval(X:term, ZeroOrOnePath(ppe), Y:var) = { (Y, yn) | yn = X or {(Y, yn)} in ppeval(X, ppe, Y) }
ppeval(X:var, ZeroOrOnePath(ppe), Y:term) = { (X, xn) | xn = Y or {(X, xn)} in ppeval(X, ppe, Y) }
ppeval(X:term, ZeroOrOnePath(ppe), Y:term) = { {} } if X = Y or ppeval(X,ppe,X) is not empty { } otherwise
ppeval(X:var, ZeroOrOnePath(ppe), Y:var) = { (X, xn) (Y, yn) | either (yn in nodes(G) and xn = yn) or {(X, xn), (Y, yn)} in ppeval(X, ppe, Y) }
我们定义一个辅助函数 ALP,用于 ZeroOrMorePath 和 OneOrMorePath 的定义。请注意,这里给出的算法用于 指定该特性。实现者可以自由采用任何方法来实现求值,只要该方法对整个查询产生相同结果。 ZeroOrMorePath 和 OneOrMorePath 形式会基于 由路径连接的不同节点返回匹配。
匹配算法基于跟随所有路径,并检测图节点(主语或对象) 何时已经在路径上被访问。
非正式地说,该算法尝试在每一步通过给定 代数属性路径表达式 ppe 的一次应用来扩展结果多重集,并记录此特定路径已经访问过哪些节点。 如果某个节点已在所考虑的路径上被访问,则它不会成为下一步的候选。
定义:函数 ALP
Let ppe be an algebraic property path expression. Let reachableTerms(x:term, ppe) be the set of RDF terms reached by repeated matches of ppe, when starting at RDF term x. ALP(x:term, ppe) = Let V = empty set of terms ALP_recurse(x:term, ppe, V) return is V ALP_recurse(x:term, ppe, V:set of RDF terms) = if ( x in V ) return add x to V X = reachableTerms(x, ppe) For n:term in X ALP_recurse(n, ppe, V) End
定义:ZeroOrMorePath 的求值
令 ppe 为一个代数属性路径 表达式。 令 G 为活动图。
ppeval(X:term, ZeroOrMorePath(ppe), vy:var) = { { (vy, n) } | n in ALP(X, ppe) } ppeval(vx:var, ZeroOrMorePath(ppe), vy:var) = { { (vx, t), (vy, n) } | t in nodes(G), (vy, n) in ppeval(t, ZeroOrMorePath(ppe), vy) } ppeval(vx:var, ZeroOrMorePath(ppe), y:term) = ppeval(y:term, ZeroOrMorePath(Inv(ppe)), vx:var) ppeval(x:term, ZeroOrMorePath(ppe), y:term) = { { } } if { (vy:var,y) } in ppeval(x, ZeroOrMorePath(ppe), vy) { } otherwise
定义:OneOrMorePath 的求值
令 ppe 为一个代数属性路径 表达式。 令 G 为活动图。
# For OneOrMorePath, we take one step of the path then start # recording nodes for results. ppeval(x:term, OneOrMorePath(ppe), vy:var) = { { (vy, t) } | t in V } where V is the set of RDF terms that is returned by the following algorithm. Let X = reachableTerms(x, ppe) Let V = the empty multiset For n in X ALP_recurse(n, ppe, V) End result is V ppeval(vx:var, OneOrMorePath(ppe), vy:var) = { { (vx, t), (vy, n) } | t in nodes(G), (vy, n) in ppeval(t, OneOrMorePath(ppe), vy) } ppeval(vx:var, OneOrMorePath(ppe), y:term) = ppeval(y:term, OneOrMorePath(Inv(ppe)), vx) ppeval(x:term, OneOrMorePath(ppe), y:term) = { { } } if { (vy:var, y) } in ppeval(x, OneOrMorePath(ppe), vy) { } otherwise
定义:否定属性集合的求值
Write μ' as the extension of a solution mapping: μ'(μ, x) = μ(x) if x is a variable μ'(μ, t) = t if t is an RDF term
Let x and y be variables or RDF terms, S a set of IRIs, and G the active graph. ppeval(x, NPS(S), y) = { μ | ∃ triple(μ'(μ, x), p, μ'(μ, y)) in G, such that the IRI of p ∉ S }
对于 SPARQL 抽象查询中剩余的每个符号,我们定义一个用于 求值的运算符。同名的 SPARQL 代数运算符用于按照“求值 语义”一节中所述,对 SPARQL 抽象查询节点进行求值。基本图模式和属性路径模式的求值已经在上文描述。
定义:Filter
令 Ω 为一个解映射多重集, expr 为一个表达式, D 为一个数据集, G 为活动图。 我们定义:
Filter(expr, Ω, D,
G) =
{ μ in Ω |
expr(μ, D, G) is an RDF term t
such that EBV(t) is "true"^^xsd:boolean }
multiplicity( μ | Filter(expr, Ω, D, G) ) = multiplicity( μ | Ω )
其中,对于每个解映射 μ, expr(μ, D, G) 是 在具有活动图 G 的数据集 D 上下文中, 相对于 μ 求值表达式 expr 的结果。
定义:Join
令 Ω1 和 Ω2 为解映射多重集。我们 定义:
Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, and μ1 and μ2 are compatible }
multiplicity( μ | Join(Ω1, Ω2) ) =
for each merge(μ1, μ2),
μ1 in
Ω1 and μ2 in Ω2 such that
μ = merge(μ1,
μ2),
sum over (μ1,
μ2),
multiplicity( μ1 | Ω1 )
* multiplicity( μ2 | Ω2
)
Join 中的某个解映射 μ 可能由被连接的多重集中不同的解 映射 μ1 和 μ2 产生。 μ 的重数是所有可能情况所得重数之和。
定义:Diff
令 Ω1 和 Ω2 为解映射多重集, expr 为一个表达式, D 为一个数据集, G 为活动图。 我们定义:
Diff(Ω1, Ω2, expr, D, G) = { μ in Ω1 | for every μ' in Ω2, any of the following conditions holds:
"true"^^xsd:boolean。
}
multiplicity( μ | Diff(Ω1, Ω2, expr, D, G) ) = multiplicity( μ | Ω1 )
其中,对于每个解映射 μ, expr(μ, D, G) 是 在具有活动图 G 的数据集 D 上下文中, 相对于 μ 求值表达式 expr 的结果。
定义:LeftJoin
令 Ω1 和 Ω2 为解映射多重集, expr 为一个表达式, D 为一个数据集, G 为活动图。 我们定义:
LeftJoin(Ω1, Ω2, expr, D, G) = Filter(expr, Join(Ω1, Ω2), D, G) ∪ Diff(Ω1, Ω2, expr, D, G)
multiplicity( μ | LeftJoin(Ω1, Ω2, expr, D, G) ) = multiplicity( μ | Filter(expr, Join(Ω1, Ω2), D, G) ) + multiplicity( μ | Diff(Ω1, Ω2, expr, D, G) )
定义:Union
令 Ω1 和 Ω2 为解映射多重集。我们 定义:
Union(Ω1, Ω2) = { μ | μ in Ω1 or μ in Ω2 }
multiplicity( μ | Union(Ω1, Ω2) ) = multiplicity( μ | Ω1 ) + multiplicity( μ | Ω2 )
定义:Minus
令 Ω1 和 Ω2 为解映射多重集。我们 定义:
Minus(Ω1, Ω2) = { μ | μ in Ω1 . ∀ μ' in Ω2, either μ and μ' are not compatible or dom(μ) and dom(μ') are disjoint }
multiplicity( μ | Minus(Ω1, Ω2) ) = multiplicity( μ | Ω1 )
之所以添加对 dom(μ) 和 dom(μ') 的附加限制,是因为否则如果
Ω2 中存在一个解映射,它与 Ω1 中的解
映射没有任何共同变量,那么 Minus(Ω1,
Ω2) 将为空,
而不管 Ω2 的其余部分如何。空解映射与
每个其他解映射都兼容,因此如果没有该限制,则对于任何
模式 P,P MINUS {} 都会为空。
定义:Extend
令 μ 为一个解映射,Ω 为解映射多重集, var 为一个变量, expr 为一个表达式, D 为一个数据集, G 为活动图。 我们定义:
Extend(Ω, var, expr, D, G) = { Extend(μ', var, expr, D, G) | μ' in Ω },
multiplicity( μ | Extend(Ω, var, expr, D, G) ) = multiplicity( μ' | Ω ) if there exists a solution mapping μ' in Ω such that μ = Extend(μ', var, expr, D, G),
multiplicity( μ | Extend(Ω, var, expr, D, G) ) = 0 if no such solution mapping μ' exists in Ω,
其中,对于每个解映射 μ',
Extend(μ', var, expr, D, G) = μ' ∪ { (var, expr(μ', D, G)) } if var not in dom(μ') and expr(μ', D, G) is an RDF term,
Extend(μ', var, expr, D, G) = μ' if var not in dom(μ') and expr(μ', D, G) is an error,
Extend(μ', var, expr, D, G) is undefined if var in dom(μ'), and
expr(μ', D, G) 是 在具有活动图 G 的数据集 D 上下文中, 相对于 μ' 求值表达式 expr 的结果。
写作 [ x | C ] 表示由满足条件 C 的元素 x 组成的序列。
定义:ToList
令 Ω 为解映射多重集。我们定义:
ToList(Ω) = a sequence of mappings μ in Ω in any order, with multiplicity( μ | Ω ) occurrences of μ
multiplicity( μ | ToList(Ω) ) = multiplicity( μ | Ω )
定义:OrderBy
令 Ψ 为解映射序列。我们定义:
OrderBy(Ψ, condition) = [ μ | μ in Ψ and the sequence satisfies the ordering condition]
multiplicity( μ | OrderBy(Ψ, condition) ) = multiplicity( μ | Ψ )
定义:Project
令 Ψ 为解映射序列,PV 为一组变量。
对于映射 μ,写作 Proj(μ, PV),表示将 μ 限制到 PV 中变量后所得的映射。
Project(Ψ, PV) = [ Proj(μ, PV) | μ in Ψ ]
multiplicity( μ | Project(Ψ, PV) ) = sum( multiplicity( μ' | Ψ ) | μ' in Ψ such that μ' = Proj(μ, PV) )
定义:Distinct
令 Ψ 为解映射序列。我们定义:
Distinct(Ψ) = [ μ | μ in Ψ ]
multiplicity( μ | Distinct(Ψ) ) = 1 for every μ ∈ Distinct(Ψ)
multiplicity( μ | Distinct(Ψ) ) = 0 for every μ ∉ Distinct(Ψ)
定义:Reduced
令 Ψ 为解映射序列。我们定义:
Reduced(Ψ) = [ μ | μ in Ψ ]
multiplicity( μ | Reduced(Ψ) ) is between 1 and multiplicity( μ | Ψ ) for every μ ∈ Reduced(Ψ)
multiplicity( μ | Reduced(Ψ) ) = 0 for every μ ∉ Reduced(Ψ)
Reduced 解序列修饰符不保证 已定义的重数。
定义:Slice
令 Ψ 为解映射序列,并令 offset 和 limit 为 非负整数。我们定义:
Slice(Ψ, offset) = Ψ0 if offset ≥ Card(Ψ)
Slice(Ψ, offset) = subseq(Ψ, offset+1, Card(Ψ)) if 0 ≤ offset < Card(Ψ)
Slice(Ψ, offset, limit) = Ψ0 if offset ≥ Card(Ψ) or limit = 0
Slice(Ψ, offset, limit) = subseq(Ψ, offset+1, Card(Ψ)) if 0 ≤ offset < Card(Ψ) and limit ≥ Card(Ψ)−offset
Slice(Ψ, offset, limit) = subseq(Ψ, offset+1, offset+limit) if 0 ≤ offset < Card(Ψ) and 0 < limit < Card(Ψ)−offset
其中 Ψ0 是空解映射序列, 并且对于每两个整数 i 和 j, subseq(Ψ, i, j) 是 Ψ 的子序列, 它从 Ψ 的第 i 个元素开始, 到 Ψ 的第 j 个元素结束。
注意,此定义假定序列以 1 为基, 且子序列在两端都是包含的 (即,以第 j 个元素结束意味着 该子序列包含 Ψ 的第 j 个元素作为最后一个元素)。
定义:ToMultiSet
令 Ψ 为一个解序列。我们定义:
ToMultiSet(Ψ) = { μ | μ in Ψ }
multiplicity( μ | ToMultiSet(Ψ) ) = multiplicity( μ | Ψ )
Group 是一个函数,它根据 解的某些属性,把解序列分组为 多个解。
Group 会针对一个 解序列 Ψ 求值表达式列表,从而产生一个 从键到解序列的偏函数。
Group(exprlist, Ψ) = { ListEval(exprlist, μ) → [ μ' | μ' in Ψ such that ListEval(exprlist, μ') and ListEval(exprlist, μ) are the same ] | μ in Ψ },
其中,如果两个列表 L 和 L'(由 ListEval 函数产生)具有 相同数量的元素,并且对于这两个列表中的每个 位置 k,以下两个条件之一为真,则认为它们 相同:
定义:ListEval
ListEval((expr1, ..., exprn), μ) returns a list (e1, ..., en), where ei = expri(μ) or error.
ListEval 保留列表 元素求值所产生的错误。
请注意,虽然 ListEval 的结果 可能包含错误,并且错误可用于 分组,但包含错误值的解会在对组和任何聚合函数求值 结束时被移除。
还要注意,ListEval((unbound), μ) 的结果是列表 (error),因为对未绑定表达式求值会产生 错误。
Aggregation 是一个函数,它计算聚合 表达式输出的标量值。它用于 SELECT 子句、HAVING 求值过程,以及 ORDER BY(在需要时)中。Aggregation 会 使用集合函数,在解的分组上计算聚合值。
令 exprlist 为表达式列表或 *;func 为集合
函数;
scalarvals 为从查询中的聚合传递来的偏函数(可能定义域为空);
并令 { key1→Ψ1, ...,
keym→Ψm } 为分组步骤产生的、
从键到
解序列的偏函数。
Aggregation 把集合函数 func 应用于给定集合,并为每个键及该键对应的一组解产生 单个值。
Aggregation(exprlist,
func, scalarvals, { key1→Ψ1,
...,
keym→Ψm } )
= { (key, F(Ψ)) | key →
Ψ in { key1→Ψ1, ...,
keym→Ψm } }
where
M(Ψ) = [ ListEval(exprlist,
μ) | μ in Ψ ]
F(Ψ) = func(M(Ψ), scalarvals), for
non-DISTINCT
F(Ψ) = func(Dedup(M(Ψ)), scalarvals),
for DISTINCT
其中 Dedup(M(Ψ)) 是序列 M(Ψ) 的一个保持顺序、无重复的版本;也就是说, Dedup(M(Ψ)) 是一个列表序列,具有以下 四个性质 (该序列中的每个这种列表都可能包含 RDF 项和 错误,因为它是由 ListEval 函数产生的)。
特殊情形:当 COUNT 与表达式
* 一起使用时,F(Ψ) 是组解序列的基数,
即 F(Ψ) = Card(Ψ),
或者如果存在 DISTINCT 关键字,则
F(Ψ) = Card(Distinct(Ψ))。
scalarvals 用于把值传递给底层集合函数,绕过
分组机制。例如,聚合表达式
GROUP_CONCAT(?x ; separator="|") 具有一个 scalarvals 参数 { "separator"
→ "|" }。
所有聚合都可以在其参数列表的第一个 token 处使用
DISTINCT 关键字。如果存在此关键字,则传给 func 的
第一个参数是 Dedup(M(Ψ))。
示例
给定具有以下值的解序列 Ψ:
| solution | ?x | ?y | ?z |
| μ1 | 1 | 2 | 3 |
| μ2 | 1 | 3 | 4 |
| μ3 | 2 | 5 | 6 |
以及查询表达式 SELECT (ex:agg(?y, ?z) AS ?agg) WHERE { ?x ?y ?z } GROUP BY ?x。
我们产生 G = Group((?x), Ψ) = { (1) → [μ1, μ2], (2) → [μ3] }
因此 Aggregation((?y, ?z), ex:agg, {},
G) =
{ ((1), eg:agg([(2, 3), (3, 4)], {})), ((2), eg:agg([(5, 6)], {})) }。
令 S1, ..., Sn 为集合列表,其中 每个集合 Si 都包含由 Aggregation 产生的从键到(聚合)值的映射。
令 K = { key | key in dom(Sj)
for some 1 ≤ j ≤ n } 为键的
集合,则
AggregateJoin(S1, ...,
Sn) = { agg1→val1,
..., aggn→valn |
key in K and key→vali in
Si for each 1 ≤ i ≤ n }
SPARQL 聚合底层的集合函数都具有共同的签名:
SetFunc(S),或 SetFunc(S, scalarvals),其中 S 是
列表序列,而 scalarvals 是
一个或多个标量值,它们通过 SPARQL 文法中聚合的 ( ...
; key=value ) 语法间接传递给集合函数。SPARQL Query 1.1 中内置聚合
支持的此功能唯一用途是 GROUP_CONCAT,
如 GROUP_CONCAT(?x ; separator=", ")。
请注意,名称 “Set Function” 有一定历史原因——传给集合 函数的参数实际上是序列。由于它与 SQL Set Functions 的共同性,该名称被保留下来,SQL Set Functions 作用于多重集。
本文档中定义的集合函数是
Count、
Sum、
Min、
Max、
Avg、
GroupConcat 和
Sample
——分别对应聚合 COUNT、
SUM、MIN、MAX、AVG、
GROUP_CONCAT 和 SAMPLE。定义见
以下各节。系统可以选择使用本地扩展来扩展此集合,使用与函数和转换相同的记法。
注意,除非使用 ; separator,
否则这要求解析器在判断使用聚合的查询中是否存在任何错误之前,
先知道某个 IRI 是指函数、转换还是
聚合。
以下各节中集合函数的定义 基于两个函数:Flatten 和 Card,它们定义如下。
Flatten 是一个函数,用于 将列表序列折叠为单个列表。 例如,[(1, 2), (3, 4)] 会变成 (1, 2, 3, 4)。
定义:Flatten
令 S 为列表序列, 即 S = [L1, L2, ..., Lm], 其中,对于每个 i ∈ {1, ..., m}, Li 是一个列表。
Flatten(S) 是列表 ( x | L in S and x in L )。
Card 是一个函数,返回 一个序列或元素列表的基数(这些元素可以是 解映射,也可以是其他类型的元素,具体取决于 上下文)。
定义:Card
给定一个序列或列表 L,Card(L) 是 L 的基数。
Count 是一个 SPARQL 集合函数,用于计数 给定表达式在聚合组中 具有已绑定、非错误值的次数。
Sum 是一个 SPARQL 集合函数,返回通过对 聚合组内的值求和而获得的数值。 类型提升按照 op:numeric-add 函数发生,并以传递方式应用 (见下方定义),因此在 ?x 具有值 1 (integer)、2.0e0 (float) 和 3.0 (decimal) 的聚合组中,SUM(?x) 的值将为 6.0 (float)。
定义:Sum
numeric Sum(sequence S)
Sum(S) = SumList(L),
其中 L = Flatten(S),并且 SumList(L) 按如下方式递归定义。
xsd:integer。
注意,L1 是 L 中的第一个元素,而 L2..n 是移除 其第一个元素后的 L。
以这种方式,Sum( [(1), (2), (3)] ) = SumList( (1, 2, 3) ) = op:numeric-add(1, op:numeric-add(2, op:numeric-add(3, 0)))。
例如,Avg([(1), (2), (3)]) = Sum([(1), (2), (3)])/Count([(1), (2), (3)]) = 6/3 = 2。
Min 是一个 SPARQL 集合函数,分别返回组中的 最小值。
它使用 SPARQL ORDER BY 排序定义,以允许对 任意类型表达式进行排序。
Max 是一个 SPARQL 集合函数,分别返回组中的 最大值。
它使用 SPARQL ORDER BY 排序定义,以允许对 任意类型表达式进行排序。
GroupConcat 是一个集合函数,它对 某个表达式在一个组中的值执行字符串连接。字符串的顺序未指定。 连接中使用的分隔符字符可以通过标量参数 SEPARATOR 给出。
定义:GroupConcat
xsd:string GroupConcat(sequence S, function scalarvals)
如果 GROUP_CONCAT 中不存在 scalarvals 参数,
则 scalarvals 被视为空函数。
令 sep 为按如下方式定义的字符串。
GroupConcat(S, scalarvals) = GCList(L, sep),
其中 L = Flatten(S) 且 GCList(L, sep) 按如下方式递归定义。
CONCAT("", L1)。
CONCAT(L1, sep,
GCList(L2..n, sep))。
注意,L1 是 L 中的第一个元素,而 L2..n 是移除 其第一个元素后的 L。
例如,GroupConcat([("a"), ("b"), ("c")], {"separator" → "."}) = GCList( ("a", "b", "c"), "." ) = "a.b.c"。
Sample 是一个集合函数,它从传给它的序列中 返回一个任意值。
例如,给定 Sample([("a"), ("b"), ("c")]), "a"、"b" 和 "c" 都是有效的返回 值。注意,对于给定输入,Sample 函数不 要求是确定性的。唯一限制是输出值必须存在于输入序列中。
我们定义 eval(D(G), AQE, μctx),作为 一个代数查询表达式 AQE 的求值, 该求值相对于具有活动图 G 的 数据集 D, 并与解映射 μctx 相关。
活动图初始为 D 的默认图,并且 μctx 初始为空解映射 μ0。
μctx
可能不同于 μ0 的情形,
是在对形式为 EXISTS { pattern } 或
NOT EXISTS { pattern } 的表达式求值时,
如17.4.1.4 NOT
EXISTS 与 EXISTS中所定义。
以下定义中使用的其他符号为:
定义:ContextSolution 的求值
eval( D(G), ContextSolution, μctx ) = 只包含 μctx、且 重数为 1 的多重集
定义:LeftJoin 的求值
eval( D(G), LeftJoin(A1, A2, F), μctx ) = LeftJoin( eval(D(G), A1, μctx), eval(D(G), A2, μctx), F, D, G )
定义:Minus 的求值
eval( D(G), Minus(A1, A2), μctx ) = Minus( eval(D(G), A1, μctx), eval(D(G), A2, μctx) )
定义:Union 的求值
eval( D(G), Union(A1, A2), μctx ) = Union( eval(D(G), A1, μctx), eval(D(G), A2, μctx) )
定义:Graph 的求值
对于每个 x,如果它是 一个 IRI 或 一个变量, eval( D(G), Graph(x, A), μctx ) 定义如下:
Ω := the empty multiset for each graph name gn in D (recall that a graph name may be an IRI or a blank node) G' := the RDF graph of the named graph with name gn in D Ω' := eval( D(G'), A, μctx ) Ω := Union( Ω, Join(Ω', μ) ), where μ = {x → gn} the result is Ω
eval( D(G), Aggregation(exprlist, func, scalarvals, Grp), μctx ) = Aggregation( exprlist, func, scalarvals, eval(D(G), Grp, μctx) )
eval( D(G), AggregateJoin(A1, ..., An), μctx ) = AggregateJoin( eval(D(G), A1, μctx), ..., eval(D(G), An, μctx) )
注意,如果 eval(D(G), Ai, μctx) 是一个错误,则会忽略它。
定义:Extend 的求值
eval( D(G), Extend(A, var, expr), μctx ) = Extend( eval(D(G), A, μctx), var, expr, D, G )
定义:OrderBy 的求值
eval( D(G), OrderBy(A, condition), μctx ) = OrderBy( eval(D(G), A, μctx), condition )
定义:ToMultiSet 的求值
eval( D(G), ToMultiset(A), μctx ) = ToMultiSet( eval(D(G), A, μctx) )
SPARQL 的整体设计可用于假定一种比简单蕴涵更复杂的 蕴涵形式的查询,方法是重写基本图 模式的匹配条件。由于以一种适用于所有蕴涵形式并能最优消除无用或 不适当冗余的通用形式陈述这些条件仍是一个开放研究问题, 本文档只给出任何此类解决方案都应满足的必要条件。这些条件需要针对 每个具体情形扩展为完整定义。
基本图模式与三元组模式之间的关系,和 RDF 图与 RDF 三元组之间的关系相同,并且许多相同术语都可应用于它们。 特别是,如果存在一个在三元组模式的项之间的双射 M,它把空白节点映射到空白节点, 并把变量、字面量和 IRI 映射到自身,使得一个三元组 ( s, p, o ) 在第一个模式中,当且仅当三元组 ( M(s), M(p), M(o) ) 在第二个模式中, 则称两个基本图模式是等价的。此定义把 RDF 图等价性的定义扩展到 基本图模式,方式是在等价模式之间保留变量名。
蕴涵体制指定
关于查询各种蕴涵体制的详细定义可见 SPARQL 1.1 蕴涵体制。
某些蕴涵体制可以把某些 RDF 图归类为不一致。例如,RDF 图:
_:x rdf:type xsd:string . _:x rdf:type xsd:decimal .
当 D 包含 XSD 数据类型时,它是 D-不一致的。对不一致图进行查询的效果 不由本规范涵盖,而必须由具体的 SPARQL 扩展来指定。
蕴涵体制 E 必须为基本图模式求值提供条件,
使得对于任何基本图模式 BGP、任何 RDF 图 G,以及任何满足
这些条件的求值,所得解多重集都能在 RDF 图
等价意义下唯一确定。我们用
Eval-E(G, BGP) 表示使用 E 对 G 上的 BGP 求值所得的解多重集。
蕴涵体制还必须满足以下条件:
SG E-entails (SG union μ1(BGP1) union ... union μn(BGPn))
这些条件并不能完全确定可能答案的集合,因为 RDF 允许无限量的冗余。因此,还必须满足以下条件。
(a) SG 通常会与 AG 图等价,但将其限制为 E-等价 允许在查询之前对源文档应用某些形式的规范化, 例如消除语义冗余。
(b) 条件 3 中的构造确保由解映射引入的任何空白节点 都以一种与 SG 中空白节点出现方式内部一致的方式使用。 这确保只有当在一个答案集中多于一个答案中出现的空白节点标识符 确实在 SG 中标识相同空白节点时,才会发生这种情况。 如果该扩展不允许绑定到空白节点,则此条件可以 简化为以下条件:
SG E-entails μ(BGP) for each solution mapping μ.
(c) 这些条件并未施加 SPARQL 关于 SG 不与 AG 或 BGP 共享 空白节点的要求。特别是,它允许 SG 实际上就是 AG。这允许 空白节点标识符在查询和源文档之间,或跨多个查询保留其含义的 查询协议。然而,当前的 SPARQL 协议规范并不支持此类协议。
(d) 由于条件 1 到 3 只是答案的必要条件,条件 4 允许合法答案集合可以以各种方式受到限制的情形。
(e) 这些条件都没有显式提及 BGP 中空白节点上的实例映射。 对于某些蕴涵体制,空白节点的存在性解释不能通过单个实例映射的存在 完全捕获。这些条件允许此类体制对查询模式中的空白节点赋予 “完全存在性”的解读。
很容易证明,对于 E 为简单蕴涵的情形,SPARQL 满足这些条件, 因为 SPARQL 关于 SG 的条件是它与 AG 图等价,但不与 AG 或 BGP 共享 空白节点(这满足第一个条件)。唯一非平凡的条件是 (3)。
对于每个解映射 μi,根据基本图 模式匹配的定义,存在一个 RDF 实例映射 σi,使得 Pi(BGPi) 是 SG 的子图,其中 Pi 是由 μi 和 σi 组合而成的模式 实例映射。由于 BGPi 和 SG 没有共同的空白节点,σi 和 μi 的值域 不包含来自 BGPi 的空白节点;因此,解映射 μi 和 Pi 的 RDF 实例映射 σi 可交换,所以 Pi(BGPi) = σi(μi(BGPi))。因此
P1(BGP1) union ... union Pn(BGPn)
= σ1(μ1(BGP1)) union ... union
σn(μn(BGPn))
= [ σ1 + ... + σn]( μ1(BGP1) union ... union
μn(BGPn) )
因为 σi RDF 实例映射的定义域全都彼此 互不相交。由于它们也与 SG 不相交,
SG union [ σ1 + ... + σn]( μ1(BGP1) union
... union μn(BGPn) )
= [ σ1 + ... + σn](SG union μ1(BGP1) union
... union μn(BGPn) )
即
SG union μ1(BGP1) union ... union μn(BGPn)
具有一个是 SG 子图的实例,因此根据 RDF 插值引理 [RDF12-SEMANTICS],它被 SG 简单蕴涵。
SPARQL 文法涵盖 SPARQL Query 和 SPARQL 1.1 Update。
SPARQL 字符串是一个 RDF 字符串,它 符合本节给出的文法。
RDF 字符串是 一个由 Unicode 码位 构成的序列,这些码位是 Unicode 标量值。 Unicode 标量值不包括 代理码位。
SPARQL 查询字符串是一个 SPARQL 字符串,它符合从 QueryUnit 产生式开始的文法。
SPARQL 更新字符串是一个 SPARQL 字符串,它符合从 UpdateUnit 产生式开始的文法。
为了与未来版本的 Unicode 兼容,此字符串中的字符可以
包含在本出版物发布之日尚未分配的 Unicode 码位(见
Unicode Identifiers and
Syntax [UAX31] 第 4 节 Pattern Syntax)。对于
带有排除字符
类的产生式(例如 [^<>'{}|^`]),字符从
范围 #x0 - #x10FFFF 中排除。
SPARQL 文档中使用三种形式的转义:
数值转义序列表示 一个 Unicode 码位的值。
数值转义序列不得产生 U+D800 到 U+DFFF 范围内的码位值, 该范围是 Unicode 代理项的范围。
| 转义序列 | Unicode 码位 |
|---|---|
| '\u' HEX HEX HEX HEX | 一个 Unicode 码位,位于 U+0000 到 U+D7FF 以及 U+E000 到 U+FFFF 范围内,对应于四个十六进制数字编码的值, 这些数字按从最高有效位到最低有效位解释。 |
| '\U' HEX HEX HEX HEX HEX HEX HEX HEX | 字符串 一个 Unicode 码位,位于 U+0000 到 U+D7FF 以及 U+E000 到 U+10FFFF 范围内,对应于八个十六进制数字编码的值, 这些数字按从最高有效位到最低有效位解释。 |
其中 HEX 是一个十六进制字符
HEX ::= [0-9] | [A-F] | [a-f]
字符串转义序列表示字符串字面量中传统上 被转义的字符:
| 转义 | Unicode 码位 |
|---|---|
| '\t' | U+0009(制表符) |
| '\n' | U+000A(换行) |
| '\r' | U+000D(回车) |
| '\b' | U+0008(退格) |
| '\f' | U+000C(换页) |
| '\"' | U+0022(引号,双引号) |
| "\'" | U+0027(撇号引号,单引号) |
| '\\' | U+005C(反斜杠) |
保留字符转义序列由一个
\
后跟这些字符之一 ~.-!$&'()*+,;=/?#@%_ 组成,
并表示
\ 右侧的字符。
转义序列可以用于以下位置:
| 数值 转义 |
字符串 转义 |
保留字符 转义 |
|
|---|---|---|---|
| IRI, 用作 RDF 项 或用于 PREFIX 或 BASE 声明 | 是 | 否 | 否 |
| 局部名称 | 否 | 否 | 是 |
| 字符串 | 是 | 是 | 否 |
转义序列通过取得与相关文法产生式匹配的 Unicode 码位序列, 然后应用以下步骤进行处理。
| 输入码位 | 输出码位 | 码位数量 |
|---|---|---|
abc\u005Cdef |
abc\def |
7 |
abc\u005Ctuv |
abc\tuv |
7 |
\u005CA |
\A |
2 |
\\u005C |
\u005C |
6 |
\u005C\u005C |
\\ |
2 |
\\\u005C |
\\ |
2 |
\\\\ |
\\ |
2 |
\u005Cn |
\n |
2 |
空白(产生式 WS)用于分隔两个
否则会被(错误)识别为一个终结符的终结符。下面规则名中
大写的名称表示空白具有意义的位置;这些规则构成一种可用于构造
SPARQL 解析器的终结符选择。空白在字符串中有意义。
否则,token 之间的空白会被忽略。
例如:
?a<?b&&?c>?d
是 token 序列:变量 '?a'、IRI
'<?b&&?c>' 以及变量 '?d',而不是一个
使用运算符 '&&' 连接两个表达式、并使用
'<'(小于)和 '>'(大于)的表达式。
SPARQL 查询中的注释采用 '#' 的形式,位于 IRI 或字符串之外,
并持续到行尾(由字符 0x0D 或
0x0A 标记)或文件结尾(如果注释标记之后没有行尾)。
注释被视为空白。
由 IRIREF 产生式和
PrefixedName(前缀展开之后)产生式匹配的文本,
在转义处理之后,必须符合 RFC 3987 “ABNF for IRI References and IRIs” 第
2.2 节中 IRI 引用的通用语法 [RFC3987]。
例如,
IRIREF <abc#def> 可以出现在
SPARQL 查询字符串中,但 IRIREF
<abc##def> 不得出现。
使用 BASE 关键字声明的基 IRI 必须是绝对 IRI。使用 PREFIX 关键字声明的前缀不得在 同一查询中重新声明。关于 BASE 和 PREFIX 的说明,见第 4.1.1 节 IRI 项语法。
空白节点不能用于:
在 SPARQL 更新 请求中。
空白节点标识符 的作用域限定在其出现所在的 SPARQL 字符串内。 在同一请求字符串中对同一空白节点标识符的不同使用 指向同一个空白节点。每个请求都会生成新的空白节点; 不能跨请求通过标识符引用空白节点。
同一空白节点标识符不能用于:
WHERE 子句INSERT DATA 操作注意,同一空白节点标识符可以出现在 SPARQL 1.1 Update 请求中的不同 QuadPattern 子句中。
文法中使用的 EBNF 记法定义于 Extensible Markup Language (XML) 1.1 [XML11] 第 6 节 Notation。
文法有两个入口点:
QueryUnitUpdateUnit。当使用名称为大写的规则作为终结符时,SPARQL 文法是 LL(1)。
注:
a' 除外;
按照 Turtle,它用于
代替 rdf:type 的 IRI
(完整形式为 http://www.w3.org/1999/02/22-rdf-syntax-ns#type)。
INSERT DATA、
DELETE DATA 和
DELETE WHERE
允许两个词之间有任意数量的空白。
为清晰起见,文法中使用单空格版本。
QuadData 和
QuadPattern
规则都使用规则 Quads。用于
INSERT DATA 和
DELETE DATA 的规则
QuadData
不得允许 quad 模式中出现变量。
DELETE WHERE、
DELETE 的 DeleteClause,
也不允许用于 DELETE DATA。
VALUES 子句的
变量列表中的变量数量,
必须对应于
RDF 项
在 DataBlock 中每个关联值列表中的数量。
VALUES 子句的
变量列表中的变量在该列表内必须唯一。
SELECT 子句中由
AS 引入的变量不得已经在作用域内。
BIND 子句中被赋值的变量,
不得已经在 GroupGraphPattern 内紧邻其前的
TriplesBlock 中被使用。
DISTINCT 关键字。
a 或变量)时
出现在三元组之后,
而不允许用于其他路径表达式。
GROUP BY 子句的查询中,
或者当 聚合 出现在
HAVING 或
ORDER BY 子句中时,
不允许在 SELECT 子句中使用 *。
[1] |
QueryUnit |
::= | Query |
[2] |
Query |
::= | Prologue
|
[3] |
UpdateUnit |
::= | Update |
[4] |
Prologue |
::= | ( BaseDecl | PrefixDecl | VersionDecl )*
|
[5] |
BaseDecl |
::= | 'BASE' IRIREF
|
[6] |
PrefixDecl |
::= | 'PREFIX' PNAME_NS IRIREF
|
[7] |
VersionDecl |
::= | 'VERSION' VersionSpecifier
|
[8] |
VersionSpecifier |
::= | STRING_LITERAL1 | STRING_LITERAL2
|
[9] |
SelectQuery |
::= | SelectClause DatasetClause* WhereClause SolutionModifier
|
[10] |
SubSelect |
::= | SelectClause WhereClause SolutionModifier ValuesClause
|
[11] |
SelectClause |
::= | 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
|
[12] |
ConstructQuery |
::= | 'CONSTRUCT' ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' ConstructTemplate SolutionModifier )
|
[13] |
DescribeQuery |
::= | 'DESCRIBE' ( VarOrIri+ | '*' ) DatasetClause* WhereClause? SolutionModifier
|
[14] |
AskQuery |
::= | 'ASK' DatasetClause* WhereClause SolutionModifier
|
[15] |
DatasetClause |
::= | 'FROM' ( DefaultGraphClause | NamedGraphClause )
|
[16] |
DefaultGraphClause
|
::= | SourceSelector |
[17] |
NamedGraphClause |
::= | 'NAMED' SourceSelector
|
[18] |
SourceSelector |
::= | iri |
[19] |
WhereClause |
::= | 'WHERE'? GroupGraphPattern
|
[20] |
SolutionModifier |
::= | GroupClause? HavingClause? OrderClause? LimitOffsetClauses?
|
[21] |
GroupClause |
::= | 'GROUP' 'BY' GroupCondition+
|
[22] |
GroupCondition |
::= | BuiltInCall | FunctionCall | '(' Expression ( 'AS' Var )? ')' | Var
|
[23] |
HavingClause |
::= | 'HAVING' HavingCondition+
|
[24] |
HavingCondition |
::= | Constraint |
[25] |
OrderClause |
::= | 'ORDER' 'BY' OrderCondition+
|
[26] |
OrderCondition |
::= | ( ( 'ASC' | 'DESC' ) BrackettedExpression )
|
[27] |
LimitOffsetClauses
|
::= | LimitClause OffsetClause? | OffsetClause LimitClause?
|
[28] |
LimitClause |
::= | 'LIMIT' INTEGER
|
[29] |
OffsetClause |
::= | 'OFFSET' INTEGER
|
[30] |
ValuesClause |
::= | ( 'VALUES' DataBlock )?
|
[31] |
Update |
::= | Prologue ( Update1 ( ';' Update )? )?
|
[32] |
Update1 |
::= | Load | Clear | Drop | Add | Move | Copy | Create | DeleteWhere | Modify | InsertData | DeleteData
|
[33] |
Load |
::= | 'LOAD' 'SILENT'? iri ( 'INTO' GraphRef )?
|
[34] |
Clear |
::= | 'CLEAR' 'SILENT'? GraphRefAll
|
[35] |
Drop |
::= | 'DROP' 'SILENT'? GraphRefAll
|
[36] |
Create |
::= | 'CREATE' 'SILENT'? GraphRef
|
[37] |
Add |
::= | 'ADD' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
|
[38] |
Move |
::= | 'MOVE' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
|
[39] |
Copy |
::= | 'COPY' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
|
[40] |
InsertData |
::= | 'INSERT DATA' QuadData
|
[41] |
DeleteData |
::= | 'DELETE DATA' QuadData
|
[42] |
DeleteWhere |
::= | 'DELETE WHERE' QuadPattern
|
[43] |
Modify |
::= | ( 'WITH' iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* 'WHERE' GroupGraphPattern
|
[44] |
DeleteClause |
::= | 'DELETE' QuadPattern
|
[45] |
InsertClause |
::= | 'INSERT' QuadPattern
|
[46] |
UsingClause |
::= | 'USING' ( iri | 'NAMED' iri )
|
[47] |
GraphOrDefault |
::= | 'DEFAULT' | 'GRAPH'? iri
|
[48] |
GraphRef |
::= | 'GRAPH' iri
|
[49] |
GraphRefAll |
::= | GraphRef | 'DEFAULT' | 'NAMED' | 'ALL'
|
[50] |
QuadPattern |
::= | '{' Quads '}'
|
[51] |
QuadData |
::= | '{' Quads '}'
|
[52] |
Quads |
::= | TriplesTemplate? ( QuadsNotTriples '.'? TriplesTemplate? )*
|
[53] |
QuadsNotTriples |
::= | 'GRAPH' VarOrIri '{' TriplesTemplate? '}'
|
[54] |
TriplesTemplate |
::= | TriplesSameSubject ( '.' TriplesTemplate? )?
|
[55] |
GroupGraphPattern |
::= | '{' ( SubSelect | GroupGraphPatternSub ) '}'
|
[56] |
GroupGraphPatternSub
|
::= | TriplesBlock? ( GraphPatternNotTriples '.'? TriplesBlock? )*
|
[57] |
TriplesBlock |
::= | TriplesSameSubjectPath ( '.' TriplesBlock? )?
|
[58] |
ReifiedTripleBlock
|
::= | ReifiedTriple PropertyList
|
[59] |
ReifiedTripleBlockPath
|
::= | ReifiedTriple PropertyListPath
|
[60] |
GraphPatternNotTriples
|
::= | GroupOrUnionGraphPattern | OptionalGraphPattern | MinusGraphPattern | GraphGraphPattern | ServiceGraphPattern | Filter | Bind | InlineData
|
[61] |
OptionalGraphPattern
|
::= | 'OPTIONAL' GroupGraphPattern
|
[62] |
GraphGraphPattern |
::= | 'GRAPH' VarOrIri GroupGraphPattern
|
[63] |
ServiceGraphPattern
|
::= | 'SERVICE' 'SILENT'? VarOrIri GroupGraphPattern
|
[64] |
Bind |
::= | 'BIND' '(' Expression 'AS' Var ')'
|
[65] |
InlineData |
::= | 'VALUES' DataBlock
|
[66] |
DataBlock |
::= | InlineDataOneVar | InlineDataFull
|
[67] |
InlineDataOneVar |
::= | Var '{' DataBlockValue* '}'
|
[68] |
InlineDataFull |
::= | ( NIL | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | NIL )* '}'
|
[69] |
DataBlockValue |
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF' | TripleTermData
|
[70] |
Reifier |
::= | '~' VarOrReifierId?
|
[71] |
VarOrReifierId |
::= | Var | iri | BlankNode
|
[72] |
MinusGraphPattern |
::= | 'MINUS' GroupGraphPattern
|
[73] |
GroupOrUnionGraphPattern
|
::= | GroupGraphPattern ( 'UNION' GroupGraphPattern )*
|
[74] |
Filter |
::= | 'FILTER' Constraint
|
[75] |
Constraint |
::= | BrackettedExpression | BuiltInCall | FunctionCall
|
[76] |
FunctionCall |
::= | iri ArgList
|
[77] |
ArgList |
::= | NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
|
[78] |
ExpressionList |
::= | NIL | '(' Expression ( ',' Expression )* ')'
|
[79] |
ConstructTemplate |
::= | '{' ConstructTriples? '}'
|
[80] |
ConstructTriples |
::= | TriplesSameSubject ( '.' ConstructTriples? )?
|
[81] |
TriplesSameSubject
|
::= | VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock
|
[82] |
PropertyList |
::= | PropertyListNotEmpty?
|
[83] |
PropertyListNotEmpty
|
::= | Verb ObjectList ( ';' ( Verb ObjectList )? )*
|
[84] |
Verb |
::= | VarOrIri | 'a'
|
[85] |
ObjectList |
::= | Object ( ',' Object )*
|
[86] |
Object |
::= | GraphNode Annotation
|
[87] |
TriplesSameSubjectPath
|
::= | VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath
|
[88] |
PropertyListPath |
::= | PropertyListPathNotEmpty?
|
[89] |
PropertyListPathNotEmpty
|
::= | ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )*
|
[90] |
VerbPath |
::= | Path |
[91] |
VerbSimple |
::= | Var |
[92] |
ObjectListPath |
::= | ObjectPath ( ',' ObjectPath )*
|
[93] |
ObjectPath |
::= | GraphNodePath AnnotationPath
|
[94] |
Path |
::= | PathAlternative |
[95] |
PathAlternative |
::= | PathSequence ( '|' PathSequence )*
|
[96] |
PathSequence |
::= | PathEltOrInverse ( '/' PathEltOrInverse )*
|
[97] |
PathElt |
::= | PathPrimary PathMod?
|
[98] |
PathEltOrInverse |
::= | PathElt | '^' PathElt
|
[99] |
PathMod |
::= | '?' | '*' | '+'
|
[100] |
PathPrimary |
::= | iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')'
|
[101] |
PathNegatedPropertySet
|
::= | PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
|
[102] |
PathOneInPropertySet
|
::= | iri | 'a' | '^' ( iri | 'a' )
|
[103] |
TriplesNode |
::= | Collection | BlankNodePropertyList
|
[104] |
BlankNodePropertyList
|
::= | '[' PropertyListNotEmpty ']'
|
[105] |
TriplesNodePath |
::= | CollectionPath | BlankNodePropertyListPath
|
[106] |
BlankNodePropertyListPath
|
::= | '[' PropertyListPathNotEmpty ']'
|
[107] |
Collection |
::= | '(' GraphNode+ ')'
|
[108] |
CollectionPath |
::= | '(' GraphNodePath+ ')'
|
[109] |
AnnotationPath |
::= | ( Reifier | AnnotationBlockPath )*
|
[110] |
AnnotationBlockPath
|
::= | '{|' PropertyListPathNotEmpty '|}'
|
[111] |
Annotation |
::= | ( Reifier | AnnotationBlock )*
|
[112] |
AnnotationBlock |
::= | '{|' PropertyListNotEmpty '|}'
|
[113] |
GraphNode |
::= | VarOrTerm | TriplesNode | ReifiedTriple
|
[114] |
GraphNodePath |
::= | VarOrTerm | TriplesNodePath | ReifiedTriple
|
[115] |
VarOrTerm |
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm
|
[116] |
ReifiedTriple |
::= | '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>'
|
[117] |
ReifiedTripleSubject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
|
[118] |
ReifiedTripleObject
|
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
|
[119] |
TripleTerm |
::= | '<<(' TripleTermSubject Verb TripleTermObject ')>>'
|
[120] |
TripleTermSubject |
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
|
[121] |
TripleTermObject |
::= | Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
|
[122] |
TripleTermData |
::= | '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>'
|
[123] |
TripleTermDataSubject
|
::= | iri |
[124] |
TripleTermDataObject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData
|
[125] |
VarOrIri |
::= | Var | iri |
[126] |
Var |
::= | VAR1 | VAR2
|
[127] |
Expression |
::= | ConditionalOrExpression
|
[128] |
ConditionalOrExpression
|
::= | ConditionalAndExpression ( '||' ConditionalAndExpression )*
|
[129] |
ConditionalAndExpression
|
::= | ValueLogical ( '&&' ValueLogical )*
|
[130] |
ValueLogical |
::= | RelationalExpression
|
[131] |
RelationalExpression
|
::= | NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
|
[132] |
NumericExpression |
::= | AdditiveExpression
|
[133] |
AdditiveExpression
|
::= | MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
|
[134] |
MultiplicativeExpression
|
::= | UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
|
[135] |
UnaryExpression |
::= | '!' UnaryExpression
|
[136] |
PrimaryExpression |
::= | BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
|
[137] |
ExprTripleTerm |
::= | '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>'
|
[138] |
ExprTripleTermSubject
|
::= | iri | Var |
[139] |
ExprTripleTermObject
|
::= | iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
|
[140] |
BrackettedExpression
|
::= | '(' Expression ')'
|
[141] |
BuiltInCall |
::= | Aggregate
|
[142] |
RegexExpression |
::= | 'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
|
[143] |
SubstringExpression
|
::= | 'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
|
[144] |
StrReplaceExpression
|
::= | 'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
|
[145] |
ExistsFunc |
::= | 'EXISTS' GroupGraphPattern
|
[146] |
NotExistsFunc |
::= | 'NOT' 'EXISTS' GroupGraphPattern
|
[147] |
Aggregate |
::= | 'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')'
|
[148] |
iriOrFunction |
::= | iri ArgList?
|
[149] |
RDFLiteral |
::= | String ( LANG_DIR | '^^' iri )?
|
[150] |
NumericLiteral |
::= | NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
|
[151] |
NumericLiteralUnsigned
|
::= | INTEGER | DECIMAL | DOUBLE
|
[152] |
NumericLiteralPositive
|
::= | INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
|
[153] |
NumericLiteralNegative
|
::= | INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
|
[154] |
BooleanLiteral |
::= | 'true' | 'false'
|
[155] |
String |
::= | STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
|
[156] |
iri |
::= | IRIREF | PrefixedName
|
[157] |
PrefixedName |
::= | PNAME_LN | PNAME_NS
|
[158] |
BlankNode |
::= | BLANK_NODE_LABEL | ANON
|
终结符的产生式:
[159] |
IRIREF |
::= | '<' ( [^<>"{}|^`\]-[#x00-#x20] | UCHAR ) * '>'
|
[160] |
PNAME_NS |
::= | PN_PREFIX? ':' |
[161] |
PNAME_LN |
::= | PNAME_NS PN_LOCAL
|
[162] |
BLANK_NODE_LABEL |
::= | '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
|
[163] |
VAR1 |
::= | '?' VARNAME |
[164] |
VAR2 |
::= | '$' VARNAME |
[165] |
LANG_DIR |
::= | '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)? |
[166] |
INTEGER |
::= | [0-9]+ |
[167] |
DECIMAL |
::= | [0-9]* '.' [0-9]+ |
[168] |
DOUBLE |
::= | ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) EXPONENT
|
[169] |
EXPONENT |
::= | [eE] [+-]? [0-9]+ |
[170] |
INTEGER_POSITIVE |
::= | '+' INTEGER
|
[171] |
DECIMAL_POSITIVE |
::= | '+' DECIMAL
|
[172] |
DOUBLE_POSITIVE |
::= | '+' DOUBLE
|
[173] |
INTEGER_NEGATIVE |
::= | '-' INTEGER
|
[174] |
DECIMAL_NEGATIVE |
::= | '-' DECIMAL
|
[175] |
DOUBLE_NEGATIVE |
::= | '-' DOUBLE
|
[176] |
STRING_LITERAL1 |
::= | "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
|
[177] |
STRING_LITERAL2 |
::= | '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
|
[178] |
STRING_LITERAL_LONG1
|
::= | "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
|
[179] |
STRING_LITERAL_LONG2
|
::= | '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
|
[180] |
ECHAR |
::= | '\' [tbnrf\"'] |
[181] |
UCHAR |
::= | ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
|
[182] |
NIL |
::= | '(' WS* ')' |
[183] |
WS |
::= | #x20 | #x9 | #xD | #xA |
[184] |
ANON |
::= | '[' WS* ']' |
[185] |
PN_CHARS_BASE |
::= | [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
|
[186] |
PN_CHARS_U |
::= | PN_CHARS_BASE | '_' |
[187] |
VARNAME |
::= | ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
|
[188] |
PN_CHARS |
::= | PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
|
[189] |
PN_PREFIX |
::= | PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
|
[190] |
PN_LOCAL |
::= | (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
|
[191] |
PLX |
::= | PERCENT | PN_LOCAL_ESC
|
[192] |
PERCENT |
::= | '%' HEX HEX |
[193] |
HEX |
::= | [0-9] | [A-F] | [a-f] |
[194] |
PN_LOCAL_ESC |
::= | '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )
|
此文法的文本版本可在此处获得。
除标记为非规范性的章节外,本规范中的所有创作指南、图表、示例和注释都是非规范性的。 本规范中的其他所有内容都是规范性的。
本文档中的关键词 MAY、MUST、MUST NOT、OPTIONAL 和 SHOULD 在且仅在它们以这里所示的全大写形式出现时, 应按 BCP 14 [RFC2119] [RFC8174] 中所述进行解释。
关于 SPARQL 查询字符串的一致性,见第 19 SPARQL 文法节;关于查询结果的一致性,见第 16 查询形式节。 关于 application/sparql-query 媒体类型的一致性,见第 22. 互联网媒体类型节。
本规范旨在与 SPARQL 1.1 Protocol [SPARQL11-PROTOCOL]、SPARQL 查询结果 XML 格式(第二 版) [RDF-SPARQL-XMLRES]、 SPARQL 1.1 查询结果 JSON 格式 [SPARQL11-RESULTS-JSON] 和 SPARQL 1.1 查询结果 CSV 和 TSV 格式 [SPARQL11-RESULTS-CSV-TSV] 结合使用。其一致性准则见这些规范。
注意,SPARQL 协议描述了一种把 SPARQL 查询传递给 SPARQL 查询处理服务,并把查询结果返回给请求实体的方式。
SPARQL 查询语言的互联网媒体类型(以前称为 MIME 类型)是
"application/sparql-query"。
建议 sparql 查询文件在所有平台上使用扩展名 ".rq"(小写)。
本节是非规范性的。
TRIPLE、isTRIPLE、SUBJECT、PREDICATE、
OBJECT
LANGDIR、hasLANG、hasLANGDIR 和 STRLANGDIR
xsd:string
0000 表示,而
不是 -0001。
详见关于
date/timeSevenPropertyModel
的注释。
EBV 定义为函数形式VALUES 中出现重复变量EXISTS 的非正式定义,在
17.4.1.4 NOT
EXISTS 与 EXISTS中加入正式定义,其中包括将 eval 函数扩展为以解映射
μctx 作为
第三个参数
RDFterm-equal 重命名为 17.4.2.2 sameValue,并
扩展其定义,以覆盖不同数据类型的字面量参数,其中这些值已知相等或已知不相等* 投影的限制sameValue(原 RDFterm-equal)和 sameTerm 移至 17.4.2 RDF
项上的函数UnaryExpression 允许 !!TODO
使用 FROM、FROM NAMED 或 GRAPH 的 SPARQL 查询可能导致指定 URI 被
解引用。这可能导致额外使用网络、磁盘或 CPU 资源,并带来
拒绝服务等相关次生问题。应考虑 统一资源
标识符(URI):通用语法
[RFC3986] 第 7 节中的安全
问题。此外,在某些情况下,file:
URI 的内容可能被访问、处理并作为结果返回,从而导致对本地资源的意外
访问。
SPARQL 请求可能导致从 SPARQL 端点发出额外请求,例如 FROM NAMED。 该端点可能位于组织的防火墙或 DMZ 内,因此 此类查询可能成为间接攻击的来源。
SPARQL 语言允许扩展,这些扩展会有其自身的安全 影响。
多个 IRI 可能具有相同外观。不同文字体系中的字符可能看起来 相似(西里尔字母 “о” 可能看起来类似拉丁字母 “o”)。一个字符后跟组合 字符可能与另一个字符具有相同的视觉表示(LATIN SMALL LETTER E 后跟 COMBINING ACUTE ACCENT 与 LATIN SMALL LETTER E WITH ACUTE 具有相同视觉表示)。SPARQL 用户必须谨慎构造查询,使其中的 IRI 与 数据中的 IRI 匹配。关于相似字符匹配的更多信息可见 Unicode 安全考量 [UTR36] 和 国际化 资源标识符(IRI) [RFC3987] 第 8 节。
TODO
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: