JSON-LD 1.1 处理算法和 API

W3C 推荐标准

此版本:
https://www.w3.org/TR/2020/REC-json-ld11-api-20200716/
最新发布版本:
https://www.w3.org/TR/json-ld11-api/
最新编辑草案:
https://w3c.github.io/json-ld-api/
测试套件:
https://w3c.github.io/json-ld-api/tests/
实现报告:
https://w3c.github.io/json-ld-api/reports/
先前版本:
https://www.w3.org/TR/2020/PR-json-ld11-api-20200507/
先前推荐标准:
https://www.w3.org/TR/2014/REC-json-ld-api-20140116/
编辑:
Gregg Kellogg(v1.0 和 v1.1)
Dave Longley (Digital Bazaar) (v1.1)
Pierre-Antoine Champin (LIRIS - Université de Lyon) (v1.1)
前任编辑:
Markus Lanthaler (Google) (v1.0)
Manu Sporny (Digital Bazaar) (v1.0)
作者:
Dave Longley (Digital Bazaar) (v1.0 和 v1.1)
Gregg Kellogg(v1.0 和 v1.1)
Markus Lanthaler (Google) (v1.0)
Manu Sporny (Digital Bazaar) (v1.0)
Niklas Lindström(v1.0)
参与:
GitHub w3c/json-ld-api
报告错误
提交历史
拉取请求

请查看 勘误,了解自发布以来报告的任何错误或 问题。

另请参阅 翻译。

本文档还提供以下非规范格式: EPUB


摘要

本规范定义了一组用于以编程方式转换 JSON-LD 文档的算法。根据所定义的转换对数据进行重构, 通常会显著简化其使用。此外,本文档还为实现这些 指定算法的开发者提出了一个应用程序编程接口(API)。

本规范描述了 JSON-LD 1.0 处理算法和 API [JSON-LD10-API] 中所定义特性的超集,并且除非另有说明, 本规范中描述的算法完全兼容使用 JSON-LD 1.0 [JSON-LD10] 创建的文档。

本文档状态

本节描述本文档在发布时的状态。 其他文档可能会取代本文档。当前 W3C 出版物列表以及本技术报告的 最新修订版可在 W3C 技术报告 索引中找到,地址为 https://www.w3.org/TR/。

本文档由 JSON-LD 工作组开发,并源自 JSON-LD 社区组的 最终报告。

有一个 实时 JSON-LD 游乐场,能够 演示本文档中描述的特性。

本规范旨在取代 JSON-LD 1.0 处理算法和 API [JSON-LD10-API] 规范。

本文档由 JSON-LD 工作组作为 推荐标准发布。

GitHub Issues 是讨论 本规范的首选方式。 或者,你也可以将意见发送到我们的邮件列表。 请将其发送至 public-json-ld-wg@w3.org (存档)。

请参阅工作组的 实现报告。

本文档已经由 W3C 成员、软件开发者以及 其他 W3C 小组和相关方审阅,并由总监认可 为 W3C 推荐标准。它是一份稳定文档,可以用作 参考材料,或被其他文档引用。W3C 在制定 推荐标准中的作用,是引起人们对该规范的关注,并促进其 广泛部署。这增强了 Web 的功能性和互操作性。

本文档由一个根据 W3C 专利政策运行的小组制作。 W3C 维护着一个 任何专利 披露的公开列表, 这些披露与该小组的交付成果有关; 该页面还包括 披露专利的说明。实际知晓某项专利并且认为该专利包含 必要权利要求 的个人,必须按照 W3C 专利政策第 6 节 披露该信息。

本文档受 2019年3月1日 W3C 流程文档管辖。

文档集合

本文档是由 JSON-LD 工作组制作的三份 JSON-LD 1.1 推荐标准之一:

1. 介绍

本节是非规范性的。

本文档是 JSON-LD 处理算法的详细规范。 本文档主要面向以下读者:

要理解本规范中的基础内容,你必须首先熟悉 JSON,其详细说明见 [RFC8259]。你还必须 理解 JSON-LD 1.1 语法规范 [JSON-LD11] 中定义的 JSON-LD 语法,它是本文档中所有算法所使用的基础语法。 要理解 API 以及它打算如何在编程环境中运行,具备 JavaScript 编程语言 [ECMASCRIPT] 和 WebIDL [WEBIDL] 的工作知识会很有帮助。要理解 JSON-LD 如何映射到 RDF, 熟悉基本的 RDF 概念会很有帮助 [RDF11-CONCEPTS]。

1.1 如何阅读本文档

本节是非规范性的。

本文档是关于 JSON 中链接数据序列化的详细规范。 本文档主要面向以下读者:

配套文档 JSON-LD 1.1 规范 [JSON-LD11] 规定了 JSON-LD 文档的语法。

要理解本规范中的基础内容,你必须首先熟悉 JSON,其详细说明见 [RFC8259]。

本文档可以突出显示自 JSON-LD 1.0 版本以来的变更。 选择以 变更。

1.2 参与贡献

本节是非规范性的。

可以通过多种方式参与本规范的开发:

1.3 排版约定

本节是非规范性的。

本规范中使用以下排版约定:

标记
标记(元素、属性、性质)、 机器可处理的值(字符串、字符、媒体类型)、 属性名 或文件名采用红橙色等宽字体。
变量
伪代码或算法描述中的变量采用斜体。
定义
术语的定义,用于本文档或其他规范中的其他位置, 采用粗体和斜体。
定义引用
对本文档中定义的引用 带下划线,并且也是指向该定义本身的活动链接。
标记定义引用
对本文档中定义的引用, 当该引用本身也是标记时,带下划线, 采用红橙色等宽字体,并且也是指向该定义本身的活动链接。
外部定义引用
对另一文档中定义的引用 带下划线,采用斜体,并且也是指向该定义本身的活动链接。
标记外部定义引用
对另一文档中定义的引用, 当该引用本身也是标记时, 带下划线,采用斜体红橙色等宽字体, 并且也是指向该定义本身的活动链接。
超链接
超链接带下划线并显示为蓝色。
[参考文献]
文档引用(规范性或资料性)用方括号括起, 并链接到参考文献部分。
自推荐标准以来的变更
自先前推荐标准以来发生变更的章节或短语 可使用 § 1.1 如何阅读本文档中的控件进行高亮显示。
注

注释位于浅绿色框中,左侧带有绿色边框,并带有绿色的“注”标题。 注释始终是资料性的。

示例位于浅卡其色框中,左侧带有卡其色边框,
并带有编号的卡其色“示例”标题。
示例始终是资料性的。示例内容采用等宽字体,并且可能进行语法着色。

示例可以有选项卡式导航按钮,
用于显示将示例转换为其他表示形式后的结果。

1.4 术语

本文档使用外部规范中定义的以下术语, 并定义 JSON-LD 特有的术语。

从其他规范导入的术语

从 ECMAScript 语言 规范 [ECMASCRIPT]、 JavaScript Object Notation(JSON)数据 交换格式 [RFC8259]、 Infra 标准 [INFRA] 和 Web IDL [WEBIDL] 导入的术语

数组
在 JSON 序列化中, 数组结构表示为 围绕零个或多个值的方括号。 值之间用逗号分隔。 在内部表示中, 列表(也称为数组)是零个或多个值的 有序集合。 虽然 JSON-LD 使用与 JSON 相同的数组表示, 但该集合默认是无序的。 虽然普通 JSON 数组中会保留顺序, 但在普通 JSON-LD 数组中不会保留顺序,除非专门定义 (见 JSON-LD 1.1 的 集合和列表 章节)。
布尔值
用于表示两种可能状态之一的值 true 和 false。
JSON 对象
在 JSON 序列化中, 对象结构 表示为一对花括号,其中包含零个或多个名称/值对(或 成员)。 名称是一个字符串。 每个名称后面跟一个冒号, 用于将名称与值分隔开。 一个逗号将一个值与后续名称分隔开。 在 JSON-LD 中,对象中的名称必须唯一。

在内部表示中,JSON 对象被描述为 映射 (见 [INFRA]), 由带有键/值对的 条目组成。

在应用程序编程接口中, 映射使用 [WEBIDL] record 描述。

null
在 JSON-LD 中使用 null 值是为了忽略或重置值。 @context 中的一个映射条目, 如果其值,或该值的 @id 为 null, 则会显式解除某个术语与 IRI 的关联。 映射条目位于 JSON-LD 文档 主体中且其值为 null 时, 其含义与未定义该映射条目相同。 如果在展开形式中将 @value、@list 或 @set 设置为 null, 则整个 JSON 对象都会被忽略。
数字
在 JSON 序列化中,数字 与大多数编程语言中使用的数字类似, 但不使用八进制和十六进制格式,并且不允许前导零。 在内部表示中, 数字等价于 long 或 double, 具体取决于该数字是否具有非零小数部分(见 [WEBIDL])。
标量
标量是字符串、数字、 true 或 false 之一。
字符串
字符串 是零个或多个 Unicode(UTF-8)字符的序列, 用双引号包围,并使用反斜杠转义(如有必要)。 字符表示为单字符字符串。

从 国际化资源标识符(IRI) [RFC3987] 导入的术语

IRI
IRI 的绝对形式,包含 scheme 以及 path 和可选的 query 与 fragment 片段。
IRI 引用
表示国际化资源 标识符的常见用法。 IRI 引用可以是 绝对的或 相对的。 但是,由此类引用产生的“IRI” 仅包括绝对 IRI; 任何相对 IRI 引用都会 解析为其绝对形式。
相对 IRI 引用
相对 IRI 引用是一个IRI 引用, 它相对于另一个IRI, 通常是文档的基准 IRI。 注意,属性、 @type 的值, 以及定义为相对于词汇表的术语的值, 都相对于词汇表映射解析, 而不是相对于基准 IRI解析。

从 RDF 1.1 概念和 抽象语法 [RDF11-CONCEPTS]、RDF Schema 1.1 [RDF-SCHEMA] 和 链接数据设计 问题 [LINKED-DATA] 导入的术语

基准 IRI
基准 IRI 是一个 在上下文中建立的 IRI, 或基于 JSON-LD 文档 位置。 基准 IRI 用于将相对 IRI 引用转换为 IRI。
空白 节点
图中的 一个节点, 它既不是 IRI, 也不是字面量。 空白 节点不包含 可解引用标识符,因为它本质上要么是临时的, 要么不包含需要从链接 数据图外部链接到的信息。 在 JSON-LD 中, 空白节点被分配一个以前缀 _: 开头的标识符。
空白节点 标识符
空白节点 标识符 是一个字符串,可用作 JSON-LD 文档范围内 空白节点的标识符。 空白节点标识符以 _: 开头。
数据集
表示 RDF 图集合的数据集, 其中恰好包括一个默认图和 零个或多个命名图。
数据类型 IRI
数据类型 IRI 是一个IRI,用于标识 决定词法形式如何映射到 字面值的数据类型。
默认 图
数据集的默认图是一个 没有名称的 RDF 图,它可以为空。
图 名称
标识命名图的 IRI 或空白 节点。
带语言标签的 字符串
带语言标签的 字符串 由一个字符串和一个非空语言标签组成, 其定义见 [BCP47]。 语言标签 必须按照 [BCP47] 的 第 2.2.9 节 一致性类别 格式良好。 处理器可以将语言标签规范化为 小写。
链接 数据
一组文档,每个文档都包含链接数据图或数据集的表示。
列表
列表是由 IRI、空白节点和字面量组成的有序序列。
字面量
以值的形式表达的对象,例如字符串或数字。 隐式或显式包含一个数据类型 IRI,并且如果数据类型是 rdf:langString,则包含一个可选的语言标签。
命名 图
命名 图 是一个由 IRI 或空白 节点标识的链接数据图。
节点
RDF 图中的节点, 是至少一个三元组的 主语和宾语。 注意,一个节点可以在一个图中同时扮演两个角色(主语和宾语), 即使是在同一个三元组中。
对象
对象是节点, 位于链接 数据图中, 且至少有一条传入边。
属性
链接数据图中有向弧的名称。 每个属性都是有方向的, 并且标注为一个IRI或一个空白节点 标识符。 只要可能,属性都应标注为 IRI。
注
使用空白 节点标识符来标注属性已过时, 并且可能会在 JSON-LD 的未来版本中移除。
另请参阅 [RDF11-CONCEPTS] 中的 谓语。
RDF 图
一个带标签的有向图, 即由有向弧连接的一组节点。 也称为链接数据图。
资源
由 资源表示的东西, 由 IRI、空白 节点或字面量指称, 表示世界中的某物(“论域”)。
主语
主语是节点, 位于链接 数据图中, 且至少有一条传出边, 通过属性与对象节点相关联。
三元组
RDF 图的一个组成部分, 包括一个主语、一个谓语和一个宾语, 表示 RDF 图的一个节点-弧-节点片段。

JSON-LD 特定术语定义

活动 上下文
在处理算法运行期间用于解析术语的 上下文。
基准方向
基准 方向是在字符串没有直接关联方向时使用的方向。 它可以使用 @direction 键在上下文中设置, 其值必须是字符串 "ltr"、"rtl" 或 null 之一。 有关规范性描述,请参阅 JSON-LD 1.1 的 上下文 定义章节。
紧凑 IRI
紧凑 IRI 的形式为 前缀:后缀, 它用作一种表达 IRI 的方式,而无需 为由前缀标识的公共词汇表中包含的每个 IRI 定义单独的术语定义。
上下文
一组用于解释 JSON-LD 文档的规则, 如 JSON-LD 1.1 的 上下文 章节中所述, 并在 JSON-LD 1.1 的上下文定义 章节中进行了规范性规定。
默认 语言
默认语言是在字符串没有直接关联语言时使用的语言。 它可以使用 @language 键在上下文中设置, 其值必须是表示 [BCP47] 语言代码的 字符串或 null。 有关规范性描述,请参阅 JSON-LD 1.1 的上下文 定义章节。
默认对象
默认 对象是具有 @default 键的映射。
展开的术语 定义
展开的术语定义是一个术语定义, 其值是一个包含一个或多个关键字键的 映射, 用于定义关联的IRI、 该属性是否为反向属性、 与字符串值关联的类型,以及容器映射。 有关规范性描述,请参阅 JSON-LD 1.1 的展开的术语 定义章节。
框架
一个 JSON-LD 文档, 它描述了使用匹配和嵌入规则转换另一个 JSON-LD 文档的形式。 框架文档允许使用额外的关键字和某些映射条目 来描述匹配和转换过程。
图 对象
图 对象表示一个命名图, 作为映射条目在节点 对象中的值。 展开时,图对象必须具有 @graph 条目, 并且还可以具有 @id 和 @index 条目。 简单图 对象 是不具有 @id 条目的 图 对象。 注意,节点对象可以具有 @graph 条目, 但如果它们包含任何其他条目, 则不被视为图对象。 仅由 @graph 组成的顶层对象也不是图对象。 注意,节点对象如果包含其他属性, 也可以表示命名图。 有关规范性描述,请参阅 JSON-LD 1.1 的图对象章节。
id 映射
id 映射是一个 映射, 它是以 @container 设置为 @id 定义的术语的值。 id 映射的值必须是节点 对象, 其键被解释为表示关联节点对象的 @id 的 IRI。 如果 id 映射中的值包含展开为 @id 的键, 则其值必须等价于 id 映射中的引用键。 有关规范性描述,请参阅 JSON-LD 1.1 的 Id 映射章节。
包含块
包含块是条目, 位于节点 对象中,其中键为 @included 或 @included 的别名, 值为一个或多个节点对象。 有关规范性描述,请参阅 JSON-LD 1.1 的包含块 章节。
索引映射
索引 映射是一个映射, 它是以 @container 设置为 @index 定义的术语的值, 其值必须是以下类型之一: 字符串、 数字、 true、 false、 null、 节点 对象、 值 对象、 列表 对象、 集合 对象,或 由零个或多个上述可能项组成的数组。 有关形式化描述,请参阅 JSON-LD 1.1 中的索引映射章节。
JSON 字面量
JSON 字面量是一个字面量,其关联的数据类型 IRI是 rdf:JSON。 在值对象 表示中,@type 的值为 @json。 JSON 字面量表示有效 JSON [RFC8259] 值。 有关规范性描述,请参阅 JSON-LD 1.1 中的 rdf:JSON 数据类型章节。
JSON-LD 文档
JSON-LD 文档是 RDF 数据集的序列化。 有关形式化描述,请参阅 JSON-LD 1.1 中的JSON-LD 语法 章节。
JSON-LD 内部 表示
JSON-LD 内部表示 是将 JSON 语法结构转换为适合直接处理的核心数据结构后的结果: 数组、映射、字符串、数字、布尔值和 null。
JSON-LD 处理器
JSON-LD 处理器是一个能够执行 JSON-LD 1.1 处理算法和 API 中定义的算法的系统。 有关形式化描述,请参阅 JSON-LD 1.1 API 中的一致性章节。
JSON-LD 值
JSON-LD 值是一个字符串、 一个数字、 true 或 false、 一个类型化 值, 或一个带语言标签的 字符串。 它表示一个 RDF 字面量。
关键字
一个特定于 JSON-LD 的字符串, 在 JSON-LD 1.1 的语法标记和 关键字章节中描述, 并在 JSON-LD 1.1 的关键字章节中进行了规范性规定,
语言 映射
语言 映射是一个映射, 它是以 @container 设置为 @language 定义的术语的值, 其键必须是表示 [BCP47] 语言代码的 字符串, 其值必须是以下类型之一: null、 字符串, 或 由零个或多个上述可能项组成的数组。 有关规范性描述,请参阅 JSON-LD 1.1 的语言映射章节。
列表对象
列表 对象是一个具有 @list 键的映射。 它还可以具有一个 @index 键,但不能有其他条目。 有关规范性描述,请参阅 JSON-LD 1.1 的列表和集合章节。
局部 上下文
使用映射指定的 上下文, 通过 @context 关键字指定。
节点 对象
节点 对象表示由 JSON-LD 文档 序列化的图中某个 节点的 零个或多个属性。 如果一个映射 存在于 JSON-LD 上下文之外,并且:
  • 它不包含 @value、@list 或 @set 关键字,或者
  • 它不是 JSON-LD 文档中最顶层的映射, 该映射除 @graph 和 @context 之外不包含任何其他 条目。
则该映射是一个节点 对象。 节点 对象中键不是关键字的条目 也称为该节点 对象的属性。 有关规范性描述,请参阅 JSON-LD 1.1 的节点对象章节。
前缀
前缀是 紧凑 IRI的第一个组成部分, 它来自一个术语,该术语映射到一个字符串; 当该字符串被前置到紧凑 IRI的后缀时, 会产生一个IRI。
处理 模式
处理模式定义了 JSON-LD 文档如何 被处理。 默认情况下,所有文档都被假定为符合本规范。 通过使用上下文中的 @version 条目定义不同版本, 发布者可以确保符合 JSON-LD 1.0 [JSON-LD10] 的处理器 不会意外处理 JSON-LD 1.1 文档,从而可能产生不同的输出。 API 提供了一个选项,用于将处理模式设置为 json-ld-1.0, 这将阻止 JSON-LD 1.1 特性被激活, 或者在上下文中的 @version 条目显式设置为 1.1 时产生错误。 本规范通过 json-ld-1.1 处理模式扩展 JSON-LD 1.0。
作用域上下文
作用域 上下文是使用 @context 条目的展开的术语 定义的一部分。它与嵌入式上下文具有相同形式。 当术语用作类型时,它定义一个类型作用域 上下文, 当用作属性时,它定义一个属性作用域 上下文。
集合对象
集合 对象是一个具有 @set 条目的 映射。 它还可以具有一个 @index 键,但不能有其他条目。 有关规范性描述,请参阅 JSON-LD 1.1 的列表和集合章节。
术语
术语是 在上下文中定义的短词, 可展开为一个IRI。 有关规范性描述,请参阅 JSON-LD 1.1 的术语章节。
术语 定义
术语定义是上下文中的一个条目, 其中键定义一个术语, 该术语可在映射 中用作键、类型,或在其他将字符串解释为词汇项的位置使用。 其值可以是一个字符串(简单术语 定义), 展开为一个IRI, 或者是一个映射(展开的术语 定义)。
类型 映射
类型映射 是一个映射值, 属于以 @container 设置为 @type 定义的 术语, 其键被解释为表示关联节点对象的 @type 的 IRI; 值必须是节点对象,或节点 对象的数组。 如果值包含一个展开为 @type 的术语, 则其值会在展开时与映射值合并。 有关规范性描述,请参阅 JSON-LD 1.1 的类型映射章节。
类型化值
类型化 值由一个值和一个类型组成, 该值是一个字符串, 该类型是一个IRI。
值 对象
值 对象是一个具有 @value 条目的映射。 有关规范性描述,请参阅 JSON-LD 1.1 的值对象章节。
词汇表 映射
词汇表映射使用 @vocab 键在上下文中设置, 其值必须是一个IRI、一个紧凑 IRI、一个术语,或 null。 有关规范性描述,请参阅 JSON-LD 1.1 的上下文 定义章节。

1.4.1 算法术语

以下术语在特定算法中使用。

活动图
处理器在处理时应使用的当前活动图的名称。
活动属性
处理器在处理时应使用的当前活动属性或关键字。 活动 属性以原始词法形式表示, 该形式用于在活动上下文中查找强制映射。
添加值
作为宏在各种算法中使用,用于将一个 value 添加到映射 (object)中由指定 key 标识的 条目。 调用可以包括一个 as array 标志,默认为 false。
  1. 如果 as array 为 true, 且 object 中 key 的值不存在 或不是数组,则将其设置为一个新的 数组, 其中包含任何原始值。
  2. 如果 value 是一个数组, 则对于 value 中的每个元素 v, 递归使用添加值 将 v 添加到 entry 中的 key。
  3. 否则:
    1. 如果 key 不是 object 中的条目, 则将 value 作为 object 中 key 的值添加。
    2. 否则
      1. 如果 object 中 key 条目的值 不是数组, 则将其设置为一个新的数组,其中包含 原始值。
      2. 将 value 追加到 object 中 key 条目的值中。
IRI 压缩
作为宏在各种算法中使用,用于减少描述压缩 表示IRI或关键字的 字符串 var 的过程所需的语言, 该过程使用一个 active context,它要么直接指定,要么来自使用此术语的算法步骤的作用域。 如果显式提供,则使用可选的 value。 除非另有规定,否则 vocab 标志默认为 true, reverse 标志默认为 false。
  1. 返回使用 IRI 压缩 算法的结果, 传入 active context、 var、 value(如果提供)、 vocab 和 result。
IRI 展开
作为宏在各种算法中使用,用于减少描述展开 表示IRI或关键字的 字符串 value 的过程所需的语言, 该过程使用一个 active context,它要么直接指定,要么来自使用此术语的算法步骤的作用域。 如果显式提供,则使用可选的 defined 和 local context 参数。 除非另有规定, document relative 标志默认为 false, vocab 标志默认为 true。
  1. 返回使用 IRI 展开 算法的结果, 传入 active context、 value、 local context(如果提供)、 defined(如果提供)、 document relative 和 vocab。
JSON-LD 输入
作为输入提供给算法的 JSON-LD 数据结构。

1.4.2 语法标记和关键字

除了 JSON-LD 1.1 语法规范 [JSON-LD11] 中定义的关键字之外, 本规范还添加了一个额外的关键字来支持 JSON-LD 1.1 成帧 [JSON-LD11-FRAMING]:

@preserve
用于由 成帧算法 生成的展开文档中,表示在 展开算法中原本可能被移除的值。

1.5 示例约定

本节是非规范性的。

注意,在本文档使用的示例中,输出 必然以 JSON 的序列化形式显示。虽然算法 描述的是对JSON-LD 内部表示的操作,但当 它们作为示例显示时,使用的是 JSON 序列化。特别是, 内部表示中使用的映射会使用 JSON 对象表示。

示例 2:示例 JSON-LD 文档
{
  "@context": {
    "name": "http://xmlns.com/foaf/0.1/name",
    "knows": "http://xmlns.com/foaf/0.1/knows"
  },
  "@id": "http://me.markus-lanthaler.com/",
  "name": "Markus Lanthaler",
  "knows": [
    {
      "name": "Dave Longley"
    }
  ]
}

在内部 表示中,上面的示例将是一个 包含 @context、@id、name 和 knows 条目的 映射, 其值可以是映射、 字符串,或由 映射或字符串值组成的数组。在 JSON 序列化中, JSON 对象用于 映射,而数组和字符串则使用许多编程语言常见的 约定进行序列化。

2. 特性

本节是非规范性的。

JSON-LD 1.1 语法规范 [JSON-LD11] 定义了一种用于 在 JSON 中表达链接数据的语法。由于使用这种语法 表达链接数据的方式不止一种,因此通常需要能够 转换 JSON-LD 文档,以便特定应用程序可以更容易地使用它们。

为了允许这些算法适配 JSON 以外的语法, 这些算法作用于 JSON-LD 内部表示, 该表示使用 数组、映射、 字符串、数字、 布尔值和 null这些通用 概念来描述 JSON 文档所表示的数据。算法作用于这种 内部表示, 而 API 入口点负责 在具体表示和内部表示之间进行转换。

JSON-LD 使用上下文来 允许链接数据 以专门适配特定人员或应用程序的方式表达。通过提供 上下文, JSON 数据可以以自然适合特定人员或应用程序的方式表达, 同时也指明这些数据应如何在全局范围内理解。 为了让人员或应用程序能够共享使用与自身不同的 上下文创建的数据, JSON-LD 处理器必须能够将文档 从一个上下文转换为另一个。 与其要求 JSON-LD 处理器为每一种可想象的 上下文切换场景编写专门代码, 不如指定一个 可以移除任何上下文的 单一算法。同样, 还可以指定另一个算法来随后应用任何 上下文。这两个 算法代表 JSON-LD 文档最基本的 转换。它们分别称为 展开和压缩。

JSON-LD 1.1 引入了与 JSON-LD 1.0 [JSON-LD10] 兼容的新特性, 但如果由 JSON-LD 1.0 处理器处理,可能会产生不同结果。 处理器默认使用 json-ld-1.1,除非 processingMode API 选项 被显式设置为 json-ld-1.0。 鼓励发布者在上下文中使用设置为 1.1 的 @version 映射条目, 以确保 JSON-LD 1.0 处理器不会误解 JSON-LD 1.1 特性。

本文档讨论了四种主要类型的转换: 展开、压缩、扁平化,以及 RDF 序列化/反序列化。

2.1 展开

本节是非规范性的。

移除上下文的算法 称为 展开。在对 JSON-LD 文档执行任何其他 转换之前,最简单的做法是 移除其中的任何上下文, 并使数据结构 更加规则。

为了了解上下文和数据结构如何影响同一数据, 下面是一个仅使用术语 且相当紧凑的 JSON-LD 示例:

下一个输入示例使用一个IRI来表达一个属性, 并使用一个映射封装一个 值,但 其余信息保持不变。

注意,这两个输入都是有效的 JSON-LD,并且都表示相同的 信息。差异在于它们的上下文信息 以及所使用的数据结构。JSON-LD 处理器可以通过采用 展开 来移除上下文, 并确保数据更加规则。

展开有两个重要目标: 从文档中移除任何上下文 信息,并确保所有值都以规则形式表示。 这些目标通过将所有条目键展开为 IRI, 并以展开形式在 数组中表达所有 值来实现。展开形式是在 JSON-LD 中表达值的 最冗长且最规则的方式;文档中的所有上下文 信息则会在每个值本地保存。 对上面的示例运行展开算法 (expand() 操作)会得到以下输出:

示例 5:使用 IRI 的展开 JSON-LD 文档
[
  {
    "@id": "http://me.markus-lanthaler.com/",
    "http://xmlns.com/foaf/0.1/name": [
      { "@value": "Markus Lanthaler" }
    ],
    "http://xmlns.com/foaf/0.1/homepage": [
      { "@id": "http://www.markus-lanthaler.com/" }
    ]
  }
]

上面的示例是 展开算法输出的 JSON-LD 序列化, 其中算法使用的映射被替换为JSON 对象。

注意,在上面的输出中,所有上下文定义都已被 移除,所有术语和 紧凑 IRI都已 展开为绝对 IRI,并且所有 JSON-LD 值都以 数组中的 展开形式表达。虽然 输出更加冗长且难以让人阅读,但它建立了一个 基准,使 JSON-LD 处理因其非常规则的 结构而更容易。

2.2 压缩

本节是非规范性的。

虽然展开会从给定 输入中移除上下文, 压缩的主要功能则是 执行相反的操作:根据特定 上下文表达给定输入。 压缩会应用一个 上下文, 该上下文会专门定制信息为特定人员或应用程序 表达的方式。这通过以应用程序特定的 术语表达数据,简化了使用 JSON 或 JSON-LD 的应用程序, 并使数据更易于人类阅读。

压缩使用开发者提供的 上下文将 IRI缩短为 术语或 紧凑 IRI, 并将以 展开形式表达的 JSON-LD 值 转换为简单值, 例如字符串 或数字。

例如,假设有以下展开后的 JSON-LD 输入文档:

示例 6: 展开后的示例文档
[
  {
    "@id": "http://me.markus-lanthaler.com/",
    "http://xmlns.com/foaf/0.1/name": [
      { "@value": "Markus Lanthaler" }
    ],
    "http://xmlns.com/foaf/0.1/homepage": [
      { "@id": "http://www.markus-lanthaler.com/" }
    ]
  }
]

此外,假设有以下开发者提供的 JSON-LD 上下文:

示例 7:JSON-LD 上下文
{
  "@context": {
    "name": "http://xmlns.com/foaf/0.1/name",
    "homepage": {
      "@id": "http://xmlns.com/foaf/0.1/homepage",
      "@type": "@id"
    }
  }
}

给定上面提供的上下文,对上面提供的 JSON-LD 输入 文档运行压缩算法 (compact() 操作)将得到以下输出:

上面的示例是 压缩算法输出的 JSON-LD 序列化, 其中算法使用的映射被替换为JSON 对象。

注意,所有IRI都已 按照 上下文中指定的方式 压缩为术语, 该上下文已被注入到输出中。虽然压缩后的输出 对人类很有用,但它也用于生成易于 编程处理的结构。压缩使开发者能够将任何展开后的文档 映射为特定于应用程序的压缩文档。虽然上面提供的上下文 将 http://xmlns.com/foaf/0.1/name 映射到 name,但它 也可以映射到开发者提供的任何其他术语。

2.3 扁平化

本节是非规范性的。

虽然展开确保文档处于统一结构中, 扁平化更进一步, 确保数据的形状 是确定性的。在展开文档中,单个 节点的 属性可能分散在多个不同的 节点 对象中。通过扁平化 文档,一个节点的所有 属性都会被收集到一个单一的 节点 对象中,并且所有空白节点 都会标记一个空白节点标识符。 这可以显著 简化某些应用程序中处理 JSON-LD 数据所需的代码。

例如,假设有以下 JSON-LD 输入文档:

示例 9:压缩形式的 JSON-LD 文档
{
  "@context": {
    "name": "http://xmlns.com/foaf/0.1/name",
    "knows": "http://xmlns.com/foaf/0.1/knows"
  },
  "@id": "http://me.markus-lanthaler.com/",
  "name": "Markus Lanthaler",
  "knows": [
    {"name": "Dave Longley"}
  ]
}

运行扁平化算法 (flatten() 操作),并将上下文设置为 null 以防止压缩, 会返回以下文档:

上面的示例是 扁平化算法输出的 JSON-LD 序列化, 其中算法使用的映射被替换为JSON 对象。

注意,在上面的输出中,一个节点的所有 属性都被收集到一个 单一的节点对象中,并且表示 “Dave Longley”的空白节点 已被分配空白节点标识符 _:b0。

为了使其更易于人类阅读,或更便于某些应用程序 处理,可以通过传入一个上下文来压缩扁平化文档。使用 与输入文档相同的上下文,扁平化并压缩后的文档 如下所示:

请注意,对文档进行扁平化并压缩后的结果 始终是一个映射, (序列化时表示为JSON 对象), 其中包含一个 @graph 条目,表示默认 图。

2.4 RDF 序列化/反序列化

本节是非规范性的。

JSON-LD 可用于按照 [RDF11-CONCEPTS] 中的描述序列化 RDF 数据。 这确保数据 可以在任何 RDF 语法之间来回转换,而不会损失保真度。

例如,假设有以下以 Turtle [TURTLE] 序列化的 RDF 输入:

示例 12:示例 Turtle 文档
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

<http://me.markus-lanthaler.com/>
  foaf:name "Markus Lanthaler" ;
  foaf:homepage <http://www.markus-lanthaler.com/> .

使用将 RDF 序列化为 JSON-LD 的算法, 开发者可以将此文档转换为展开后的 JSON-LD:

示例 13:转换为 JSON-LD 的示例 Turtle 文档
[
  {
    "@id": "http://me.markus-lanthaler.com/",
    "http://xmlns.com/foaf/0.1/name": [
      { "@value": "Markus Lanthaler" }
    ],
    "http://xmlns.com/foaf/0.1/homepage": [
      { "@id": "http://www.markus-lanthaler.com/" }
    ]
  }
]

上面的示例是 将 RDF 序列化为 JSON-LD 的算法输出的 JSON-LD 序列化, 其中算法使用的映射被替换为JSON 对象。

注意,上述输出可以很容易地使用上一节概述的技术进行压缩。 也可以使用将 JSON-LD 反序列化为 RDF 的 算法将 JSON-LD 文档反序列化回 RDF。

3. 一致性

除标记为非规范性的章节外,本规范中的所有编写指南、图表、示例和注释都是非规范性的。 本规范中的其他所有内容都是规范性的。

本文档中的关键词 MAY、MUST、MUST NOT 和 SHOULD 应按照 BCP 14 [RFC2119] [RFC8174] 中所述进行解释,但仅当它们像这里所示那样全部大写时才如此。

有两类产品可以声称符合本 规范:JSON-LD 处理器 和 RDF 序列化器/反序列化器。

符合规范的 JSON-LD 处理器 是一个能够执行 展开、压缩 和 扁平化操作的系统, 其方式与 本规范中定义的算法一致。

JSON-LD 处理器MUST NOT 尝试纠正格式错误的 IRI 或语言标签; 但是,它们 SHOULD 发出验证警告。 除了在 相对 IRI 和绝对 IRI 之间转换外,IRI 不会被修改。

符合规范的 RDF 序列化器/反序列化器是一个能够按照 本规范中的定义 将 JSON-LD 反序列化为 RDF 并 将 RDF 序列化为 JSON-LD 的系统。

除非使用 processingMode API 选项指定, 否则处理模式 通过局部上下文中的 @version 条目设置, 并影响包括展开和压缩在内的算法行为。 一旦设置,尝试更改为不同处理模式就是错误, 并且处理器 MUST 生成 processing mode conflict 错误并中止进一步处理。

本规范中的算法通常更注重清晰性而非效率。因此,JSON-LD 处理器可以 以任何所需方式实现本规范中给出的算法, 只要最终结果与通过本规范算法获得的结果不可区分即可。

在描述对关键字进行操作的算法步骤中,这些步骤 也适用于关键字别名。

注

实现者可以通过成功通过 JSON-LD 测试套件中的测试用例, 部分检查其对本规范的一致性级别。 但请注意,通过测试 套件中的所有测试并不意味着完全符合本规范。它只意味着 该实现符合测试套件所测试的方面。

本规范使用以下命名空间前缀:

前缀 IRI
rdf http://www.w3.org/1999/02/22-rdf-syntax-ns#
xsd http://www.w3.org/2001/XMLSchema#

4. 上下文处理算法

以下章节描述用于处理 JSON-LD 上下文的算法。

4.1 上下文处理算法

在处理 JSON-LD 数据结构时,每条处理规则都使用 活动上下文提供的信息应用。本 节描述如何生成活动上下文。

活动上下文 由以下内容组成:

每个术语 定义由以下内容组成:

术语定义 不仅可用于将术语 映射到 IRI,还可用于将术语映射到关键字, 在这种情况下它称为关键字别名。

处理时,active context 会被初始化为 具有 null 逆上下文, 且没有任何术语 定义、 词汇表 映射、默认基准方向或默认 语言。 如果在处理期间遇到局部上下文, 则会通过克隆现有的 active context 来创建新的 active context。然后将 局部上下文中的信息 合并到新的 active context 中。 鉴于局部 上下文可能包含 对远程上下文的引用,这包括对它们的检索。

4.1.1 概述

本节是非规范性的。

首先,我们通过克隆 当前活动上下文来准备一个新的 活动上下文 result。 然后,我们将原始 局部上下文 的形式规范化为数组。 局部上下文 可以是 映射、 字符串,或包含 二者组合的数组。最后,我们按如下方式处理 局部 上下文数组中包含的每个 上下文。

如果上下文是字符串,则它 表示对 远程上下文的引用。我们解引用远程上下文,并将上下文 替换为检索到的 JSON-LD 文档中顶层对象的 @context 条目的值。 如果不存在这样的条目,则检测到 invalid remote context。 否则,我们通过递归使用 此算法来处理上下文,并确保不存在循环引用。

如果上下文是映射, 则它是上下文定义。 我们首先通过处理六个特定关键字: @base、 @direction、 @language、 @propagate、 @version 和 @vocab, 来更新 基准 IRI、 默认基准 方向、 默认 语言、 上下文传播、 处理模式 和词汇表映射。 这些会在局部上下文中的任何其他 条目之前处理,因为 它们会影响其他条目的处理方式。 如果上下文包含 @import,则检索它并将其反向合并 到包含它的上下文中,从而允许 JSON-LD 1.0 上下文升级到 JSON-LD 1.1。 请注意,在处理远程上下文时会忽略 @base。

如果上下文不应传播, 则会保留对先前 上下文的引用,以便 在进入新的节点对象时回滚。 默认情况下,除类型作用域上下文外,所有上下文都会传播。

初始化活动 上下文时, 原始基准 URL的值 会从包含初始上下文的文档的原始 documentUrl 初始化(如果可用), 否则从 base API 选项初始化。 这在通过将活动上下文 设置为 null 来重置它时是必要的, 以保留原始默认基准 IRI。

初始化时,或当 活动 上下文的任何条目发生变化时, 或任何关联的术语定义被添加、 更改或移除时, 逆上下文字段 在活动 上下文中会被设置为 null。

然后,对于局部上下文中的每个其他 条目,我们更新 result 中的术语 定义。由于 局部上下文 中的术语 定义 本身可能包含术语或 紧凑 IRI, 我们可能需要递归。 这样做时,必须确保不存在循环依赖, 这是一种错误。在处理完任何 术语 定义依赖后, 我们更新当前的术语定义, 它可能是关键字 别名。

最后,我们返回 result 作为新的活动上下文。

4.1.2 算法

此算法指定如何使用局部 上下文更新新的活动上下文。 该算法接受三个必需的 和四个可选的 输入变量。 必需输入是 active context、 local context, 以及用于解析相对上下文 URL 的 base URL。 可选输入是 一个数组 remote contexts, 默认为新的空数组,用于检测循环上下文 包含, override protected,默认为 false, 用于允许更改受保护术语, propagate,默认为 true, 用于标记与非传播上下文关联的术语 定义, 以及 validate scoped context,默认为 true, 用于在验证可能递归的作用域上下文时限制递归。

  1. 将 result 初始化为克隆 active context的结果, 并将逆上下文设置为 null。
  2. 如果 local context 是包含成员 @propagate 的对象, 则其值 MUST 为布尔值 true 或 false, 将 propagate 设置为该值。
    注
    错误处理在步骤 5.11中执行。
  3. 如果 propagate 为 false,并且 result 没有先前上下文,则将 result 中的先前上下文 设置为 active context。
  4. 如果 local context 不是数组, 则将 local context 设置为仅包含 local context 的数组。
  5. 对 local context 中的每个项 context:
    1. 如果 context 是 null:
      1. 如果 override protected 为 false 且 active context 包含任何受保护的术语 定义, 则检测到 invalid context nullification 并中止处理。
      2. 将 result 初始化为一个 新初始化的活动 上下文, 将基准 IRI和原始基准 URL都设置为 active context 中原始基准 URL的值, 并且如果 propagate 为 false, 将 result 中的先前上下文 设置为 result 的先前值。
      3. 继续处理下一个 context。
    2. 如果 context 是字符串,
      1. 将 context 初始化为将 context 相对于 base URL 解析的结果。如果 base URL 不是有效的IRI, 则 context MUST 是有效的IRI,否则 检测到 loading document failed 错误 并中止处理。
        注
        base URL 通常不同于 base 或 active context 的基准 IRI。
      2. 如果 validate scoped context 为 false, 且 remote contexts 已经包含 context, 则不再进一步处理 context,并继续处理 local context 中任何下一个 context。
      3. 如果 remote contexts 数组中的条目数 超过处理器定义的限制,则检测到 context overflow 错误并中止处理; 否则,将 context 添加到 remote contexts。
      4. 如果 context 先前已被解引用, 则处理器 MUST NOT 进行 进一步解引用,并且 context 被设置为 先前建立的内部表示: 将 context document 设置为先前解引用的文档, 并将 loaded context 设置为 context document 中该文档的 @context 条目的值。
        注
        只需保留 @context 条目。
      5. 否则,将 context document 设置为通过使用 LoadDocumentCallback 解引用 context 所获得的 RemoteDocument, 传入 context 作为 url, 并传入 http://www.w3.org/ns/json-ld#context 作为profile 以及requestProfile。
        1. 如果 context 无法被 解引用, 或者 context document 中的 document 无法转换为内部表示 , 则检测到 loading remote context failed 错误并中止处理。
        2. 如果 document 没有 带有 @context 条目的 顶层映射,则检测到 invalid remote context 并中止处理。
        3. 将 loaded context 设置为该条目的值。
      6. 将 result 设置为递归调用此算法的结果, 传入 result 作为 active context, loaded context 作为 local context, context document 的 documentUrl 作为 base URL, remote contexts 的副本, 以及 validate scoped context。
        注
        如果 context 先前已被解引用, 处理器MUST 提供保留该上下文的 base URL 的机制, 用于此步骤,以便能够解析处理期间可能遇到的任何 相对上下文 URL。
      7. 继续处理下一个 context。
    3. 如果 context 不是映射,则检测到 invalid local context 错误并中止处理。
    4. 否则,context 是一个上下文 定义。
    5. 如果 context 有 @version 条目:
      1. 如果关联值不是 1.1, 则检测到 invalid @version value 并中止处理。
        注
        使用 1.1 作为 @version 的值,旨在 使 JSON-LD 1.0 处理器停止处理。 尽管它显然意在与 JSON-LD 1.1 相关,但它并不 以其他方式遵循语义化版本控制的要求。 在比较具有非零小数部分的数字 值时,实现可能需要 特殊 考虑。
      2. 如果处理 模式 被设置为 json-ld-1.0, 则检测到 processing mode conflict 错误并中止处理。
    6. 如果 context 有 @import 条目:
      1. 如果处理 模式是 json-ld-1.0, 则检测到 invalid context entry 错误并中止处理。
      2. 否则,如果 @import 的值不是字符串, 则检测到 invalid @import value 错误并中止处理。
      3. 将 import 初始化为将 @import 的值相对于 base URL 解析的结果。
      4. 使用 LoadDocumentCallback 解引用 import,传入 import 作为 url, 并传入 http://www.w3.org/ns/json-ld#context 作为profile 以及requestProfile。
      5. 如果 import 无法被解引用, 或无法转换为内部 表示, 则检测到 loading remote context failed 错误并中止处理。
      6. 如果解引用的文档没有 带有 @context 条目的 顶层映射, 或者如果 @context 的值不是上下文 定义 (即它不是映射), 则检测到 invalid remote context 并中止处理;否则, 将 import context 设置为该条目的值。
      7. 如果 import context 有 @import 条目, 则检测到 invalid context entry 错误并中止处理。
      8. 将 context 设置为将 context 合并到 import context 中的结果,用 context 中的条目替换共有条目。
    7. 如果 context 有 @base 条目,并且 remote contexts 为空,即当前 正在处理的上下文不是远程上下文:
      1. 将 value 初始化为与 @base 条目关联的值。
      2. 如果 value 为 null,则移除 result 的基准 IRI。
      3. 否则,如果 value 是IRI, 则将 result 的基准 IRI设置为 value。
      4. 否则,如果 value 是相对 IRI 引用 并且 result 的基准 IRI不是 null, 则将 result 的基准 IRI设置为 将 value 相对于 result 当前基准 IRI 解析的结果。
      5. 否则,检测到 invalid base IRI 错误并中止处理。
    8. 如果 context 有 @vocab 条目:
      1. 将 value 初始化为与 @vocab 条目关联的值。
      2. 如果 value 是null,则从 result 中移除 任何词汇表 映射。
      3. 否则,如果 value 是 IRI 或空白 节点标识符,则 result 的词汇表 映射 被设置为 使用 true 作为 document relative 对 value 进行 IRI 展开的结果 。 如果它不是IRI或空白 节点标识符,则检测到 invalid vocab mapping 错误并中止处理。
        注
        使用空白 节点标识符作为 @vocab 的值已过时, 并且可能会在 JSON-LD 的未来版本中移除。
    9. 如果 context 有 @language 条目:
      1. 将 value 初始化为与 @language 条目关联的值。
      2. 如果 value 为 null,则从 result 中移除 任何默认 语言。
      3. 否则,如果 value 是字符串,则将 result 的默认 语言设置为 value。 如果它不是字符串,则检测到 invalid default language 错误并中止处理。 如果 value 按照 [BCP47] 的第 2.2.9 节 不是格式良好的, 处理器 SHOULD 发出 警告。
        注
        处理器 MAY 将语言 标签规范化为小写。
    10. 如果 context 有 @direction 条目:
      1. 如果处理 模式是 json-ld-1.0, 则检测到 invalid context entry 错误并中止处理。
      2. 将 value 初始化为与 @direction 条目关联的值。
      3. 如果 value 为 null,则从 result 中移除 任何基准 方向。
      4. 否则,如果 value 是字符串,则将 result 的基准 方向设置为 value。如果它不是 null、"ltr" 或 "rtl",则检测到 invalid base direction 错误并中止处理。
    11. 如果 context 有 @propagate 条目:
      1. 如果处理 模式是 json-ld-1.0, 则检测到 invalid context entry 错误并中止处理。
      2. 否则,如果 @propagate 的值不是布尔值 true 或 false, 则检测到 invalid @propagate value 错误并中止处理。
        注
        先前上下文实际上在 此算法的更早位置设置; 前两个步骤仅用于错误检查。
    12. 创建一个映射 defined,用于跟踪 某个术语是否已经被定义, 或当前是否正在递归期间被定义。
    13. 对于 context 中每个 key-value 对,其中 key 不是 @base、 @direction、 @import、 @language、 @propagate、 @protected、 @version 或 @vocab, 调用 创建术语定义算法, 传入 result 作为 active context, context 作为 local context,key, defined, base URL, context 中 @protected 条目的值(如果有)作为 protected, override protected, 以及 remote contexts 的副本。
  6. 返回 result。

4.2 创建术语定义

此算法由 上下文处理算法 调用,用于在活动上下文中,为正在 局部 上下文中处理的术语 创建术语 定义。

4.2.1 概述

本节是非规范性的。

术语 定义通过 解析给定局部上下文中关于 给定术语的信息来创建。如果 给定术语是 紧凑 IRI,则它可以通过 依赖其前缀自身具有的 术语 定义,省略IRI 映射。如果该前缀是 条目,位于局部 上下文中,那么在继续之前,必须先通过递归创建其术语定义。 由于一个术语 定义可能依赖其他 术语 定义,因此必须 使用一种机制来检测循环依赖。这里采用的解决方案 使用一个映射 defined,它跟踪某个 术语是否已被定义, 或当前是否正在 被定义。此映射会在尝试任何递归之前进行检查。

在一个术语的所有依赖项都已定义后, 会考虑给定术语在局部上下文中的其余信息, 创建适当的 IRI 映射、容器映射、 以及 类型映射、 语言映射, 或方向映射 用于该术语。

4.2.2 算法

该算法有四个必需输入,以及五个可选输入。 必需输入是 active context、 local context、 term, 以及映射 defined。 可选输入是 base URL,默认为 null; protected,默认为 false; 以及 override protected,默认为 false, 它用于允许更改受保护术语; 一个数组 remote contexts, 默认为新的空数组,用于检测循环 上下文包含; 以及 validate scoped context,默认为 true, 用于在验证可能递归的作用域上下文时限制递归。

  1. 如果 defined 包含条目 term,且关联的 值为 true(表示 术语 定义已经创建),则返回。否则, 如果其值为 false,则检测到 cyclic IRI mapping 错误并中止处理。
  2. 如果 term 是空字符串(""), 则检测到 invalid term definition 错误并中止处理。 否则,将与 defined 的 term 条目关联的值设置为 false。这表示术语定义 现在正在创建,但尚未完成。
  3. 将 value 初始化为与 local context 中 term 条目关联的值的副本。
  4. 如果 term 是 @type, 并且处理模式为 json-ld-1.0, 则检测到 keyword redefinition 错误, 并中止处理。 此时, value MUST 是一个映射,且仅包含以下 条目中的任一个或二者:
    • 一个 @container 条目,其值为 @set。
    • 一个 @protected 条目。
    任何其他值都意味着已检测到 keyword redefinition 错误, 并中止处理。
  5. 否则,由于关键字不能被覆盖, term MUST NOT 是关键字,否则 检测到 keyword redefinition 错误并中止处理。 如果 term 具有关键字的形式 (即它匹配 [RFC5234] 中的 ABNF 规则 "@"1*ALPHA), 则返回;处理器 SHOULD 生成警告。
  6. 将 previous definition 初始化为 active context 中 term 的任何现有 术语 定义, 并从 active context 中移除该术语定义。
  7. 如果 value 为 null, 将其转换为一个映射,该映射由单个条目组成, 其键为 @id,值为 null。
  8. 否则,如果 value 是字符串,则将其 转换为一个映射,该映射由单个条目组成, 其键为 @id,值为 value。 将 simple term 设置为 true。
  9. 否则,value MUST 是一个映射;如果不是, 则检测到 invalid term definition 错误并中止处理。 将 simple term 设置为 false。
  10. 创建一个新的术语定义 definition, 将前缀标志初始化为 false, 将受保护初始化为 protected, 并将反向 属性初始化为 false。
  11. 如果 value 有 @protected 条目, 将 definition 中的受保护标志设置为该条目的值。 如果 @protected 的值不是布尔值, 则检测到 invalid @protected value 错误并 中止处理。 如果处理模式为 json-ld-1.0, 则检测到 invalid term definition 并中止处理。
  12. 如果 value 包含条目 @type:
    1. 将 type 初始化为与 @type 条目关联的值,该值 MUST 是字符串。否则, 检测到 invalid type mapping 错误并中止处理。
    2. 将 type 设置为 对 type 进行IRI 展开的结果, 使用 local context 和 defined。
    3. 如果展开后的 type 是 @json 或 @none,且处理模式为 json-ld-1.0, 则检测到 invalid type mapping 错误并中止处理。
    4. 否则,如果展开后的 type 既不是 @id,也不是 @json, 也不是 @none, 也不是 @vocab, 也不是IRI, 则检测到 invalid type mapping 错误并中止处理。
    5. 将 definition 的类型映射设置为 type。
  13. 如果 value 包含条目 @reverse:
    1. 如果 value 包含 @id 或 @nest 条目,则 检测到 invalid reverse property 错误并中止处理。
    2. 如果与 @reverse 条目关联的值 不是字符串,则 检测到 invalid IRI mapping 错误并中止处理。
    3. 如果与 @reverse 条目关联的值是一个 具有关键字形式的字符串 (即它匹配 [RFC5234] 中的 ABNF 规则 "@"1*ALPHA), 则返回;处理器 SHOULD 生成警告。
    4. 否则,将 definition 的IRI 映射设置为 对与 @reverse 条目关联的值进行 IRI 展开 的结果, 使用 local context 和 defined。 如果结果不具有形式为 IRI或空白节点 标识符, 则检测到 invalid IRI mapping 错误并中止处理。
    5. 如果 value 包含 @container 条目, 将 definition 的容器映射 设置为包含其值的数组; 如果其值既不是 @set,也不是 @index,也不是 null,则检测到 invalid reverse property 错误(反向属性仅支持 set 和 index 容器)并中止处理。
    6. 将 definition 的反向 属性标志 设置为 true。
    7. 将 active context 中 term 的术语定义设置为 definition,并将与 defined 的条目 term关联的 值设置为 true,然后返回。
  14. 如果 value 包含条目 @id,且其值 不等于 term:
    1. 如果 value 的 @id 条目 为 null,则该术语不用于 IRI 展开,但会 保留以便检测该术语未来的重新定义。
    2. 否则:
      1. 如果与 @id 条目关联的值不是字符串,则检测到 invalid IRI mapping 错误并中止处理。
      2. 如果与 @id 条目关联的值 不是关键字,但 具有关键字的形式 (即它匹配 [RFC5234] 中的 ABNF 规则 "@"1*ALPHA), 则返回;处理器 SHOULD 生成 警告。
      3. 否则,将 definition 的IRI 映射设置为 对与 @id 条目关联的值进行 IRI 展开 的结果, 使用 local context 和 defined。 如果得到的IRI 映射 既不是关键字,也不是 IRI,也不是空白 节点标识符,则检测到 invalid IRI mapping 错误并中止处理;如果它等于 @context,则检测到 invalid keyword alias 错误并中止处理。
      4. 如果 term 包含冒号 (:),且该冒号不在 term 的第一个或最后一个字符处, 或者如果它在任何位置包含斜杠(/):
        1. 将与 defined 的 term 条目关联的值设置为 true。
        2. 如果使用 local context 和 defined 对 term 进行IRI 展开的结果 与 definition 的IRI 映射不同, 则检测到 invalid IRI mapping 错误并中止处理。
      5. 如果 term 既不包含冒号(:)也不包含 斜杠(/), simple term 为 true, 并且如果 definition 的IRI 映射 是一个以gen-delim 字符结尾的IRI, 或者是空白 节点标识符, 则将 definition 中的前缀标志设置为 true。
  15. 否则,如果 term 包含冒号(:) 且该冒号位于第一个字符之后的任何位置:
    1. 如果 term 是一个紧凑 IRI,且其 前缀 是 local context 中的一个条目, 则发现一个依赖项。递归使用此算法,并传入 active context、local context、该 前缀作为 term,以及 defined。
    2. 如果 term 的前缀在 active context 中有一个 术语 定义,则将 definition 的IRI 映射设置为 将与前缀的 IRI 映射关联的值和 term 的 suffix 连接的结果。
    3. 否则,term 是一个IRI或 空白节点 标识符。将 definition 的IRI 映射 设置为 term。
  16. 否则,如果 term 包含斜杠(/):
    1. Term 是一个相对 IRI 引用。
    2. 将 definition 的IRI 映射设置为 对 term 进行IRI 展开的结果。 如果得到的IRI 映射不是IRI,则检测到 invalid IRI mapping 错误并中止处理。
  17. 否则,如果 term 是 @type,则将 definition 的IRI 映射 设置为 @type。
  18. 否则,如果 active context 有 词汇表映射,则 definition 的IRI 映射 被设置为将与词汇表映射关联的值和 term 连接的结果。 如果它没有词汇表映射,则检测到 invalid IRI mapping 错误并中止处理。
  19. 如果 value 包含条目 @container:
    1. 将 container 初始化为与 @container 条目关联的值,该值 MUST 是 @graph、 @id、 @index、 @language、 @list、 @set、 @type, 或者是一个数组, 其中只包含这些关键字中的任意一个; 一个数组, 其中包含 @graph 以及 @id 或 @index 之一,并可选地 包含 @set; 或者是一个数组, 其中以任意顺序包含 @set 和 @index、@graph、 @id、@type、 @language 中任意项的组合 。 否则,检测到 invalid container mapping 并中止处理。
    2. 如果容器值 是 @graph、@id 或 @type,或者不是 字符串, 则在处理模式为 json-ld-1.0 时,生成 invalid container mapping 错误并中止处理。
    3. 将 definition 的容器映射设置为 container, 如有必要,将其强制转换为数组。
    4. 如果 definition 的容器映射包含 @type:
      1. 如果 definition 中的 type mapping 未定义,则将其设置为 @id。
      2. 如果 definition 中的 type mapping 既不是 @id 也不是 @vocab, 则检测到 invalid type mapping 错误并中止处理。
  20. 如果 value 包含条目 @index:
    1. 如果处理模式为 json-ld-1.0,或 容器 映射不包含 @index, 则检测到 invalid term definition 并中止处理。
    2. 将 index 初始化为与 @index 条目关联的值。 如果对该值进行 IRI 展开的结果不是IRI, 则检测到 invalid term definition 并中止处理。
    3. 将 definition 的索引 映射设置为 index
  21. 如果 value 包含条目 @context:
    1. 如果处理模式为 json-ld-1.0,则检测到 invalid term definition 并中止处理。
    2. 将 context 初始化为与 @context 条目关联的值,该值被视为局部 上下文。
    3. 调用上下文处理算法, 使用 active context、context 作为 local context、 base URL、 true 作为 override protected、 remote contexts 的副本, 以及 false 作为 validate scoped context。 如果检测到任何错误,则检测到 invalid scoped context 错误 并中止处理。
      注

      上下文 处理算法的结果 会被丢弃;调用它是为了在定义时检测错误。 如果使用该上下文,它将在活动 上下文中重新处理并应用, 作为展开或压缩的一部分。

    4. 将 definition 的局部上下文设置为 context, 并将基准 URL设置为 base URL。
  22. 如果 value 包含条目 @language,且 不包含条目 @type:
    1. 将 language 初始化为与 @language 条目关联的值,该值 MUST 是 null 或字符串。 如果 language 按照 [BCP47] 的 第 2.2.9 节 不是格式良好的, 处理器 SHOULD 发出警告。 否则,检测到 invalid language mapping 错误并中止处理。
    2. 将 definition 的语言映射设置为 language。
      注
      处理器 MAY 将 语言 标签规范化为小写。
  23. 如果 value 包含条目 @direction,且 不包含条目 @type:
    1. 将 direction 初始化为与 @direction 条目关联的值,该值 MUST 是 null、 "ltr" 或 "rtl"。否则,检测到 invalid base direction 错误并中止处理。
    2. 将 definition 的方向映射 设置为 direction。
  24. 如果 value 包含条目 @nest:
    1. 如果处理模式为 json-ld-1.0,则检测到 invalid term definition 并中止处理。
    2. 将 definition 中的嵌套 值初始化为与 @nest 条目关联的值,该值 MUST 是字符串,并且 MUST NOT 是除 @nest 以外的关键字。否则,检测到 invalid @nest value 错误并中止处理。
  25. 如果 value 包含条目 @prefix:
    1. 如果处理模式为 json-ld-1.0,或者如果 term 包含冒号(:)或斜杠(/),则检测到 invalid term definition 并中止处理。
    2. 将前缀 标志设置为与 @prefix 条目关联的值,该值 MUST 是布尔值。否则,检测到 invalid @prefix value 错误并中止处理。
    3. 如果 definition 的前缀 标志被设置为 true, 且其IRI 映射是关键字, 则检测到 invalid term definition 并中止处理。
  26. 如果 value 包含除 @id、 @reverse、@container、 @context、 @direction、 @index、 @language、 @nest、 @prefix、 @protected 或 @type 之外的任何条目, 则检测到 invalid term definition 错误并 中止处理。
  27. 如果 override protected 为 false, 且 previous definition 存在并且受保护:
    1. 如果 definition 与 previous definition 不相同 (除了受保护的值之外), 则检测到 protected term redefinition 错误, 并中止处理。
    2. 将 definition 设置为 previous definition,以保留 受保护的值。
  28. 将 active context 中 term 的术语 定义设置为 definition,并将与 defined 的条目 term关联的值设置为 true。

4.3 逆上下文创建

当有多个术语可被选择 用于压缩一个 IRI 时,必须确保术语 选择既是确定性的,又表示最适合上下文的 选择,同时还要考虑算法复杂度。

为了进行术语 选择,引入了 逆上下文的概念。 逆上下文 本质上是一个反向查找表,它将 容器映射、 类型映射和 语言映射映射到给定 活动上下文中的简单 术语。 只有在 逆上下文用于 压缩时,才需要为 活动上下文 生成它。

要使用逆 上下文,会为与某个 IRI 关联的特定值 收集首选 容器映射列表,以及 类型映射或 语言映射。 然后这些参数 会传给术语选择算法, 该算法将找到最适合 匹配该值的映射的术语。

4.3.1 概述

本节是非规范性的。

要为给定 活动 上下文创建逆 上下文,会访问 活动 上下文中的每个术语,按长度排序,最短者 优先(平局时选择字典序最小的 术语)。对于每个术语,都会为 容器映射和 类型映射 或语言映射 的每一种可能组合,在 逆上下文中添加一个条目, 这些组合能够合法匹配该 术语。非法匹配 包括值的类型映射或 语言映射与该 术语的对应映射之间存在差异。 如果某个术语没有 容器映射、 类型映射或 语言映射(或这些项的某种组合), 则它会在逆上下文中使用特殊 键 @none 拥有一个条目。这允许 术语选择算法在无法为特定 IRI和值组合获得更 具体匹配的术语时,回退到 选择更通用的术语。

虽然规范化语言标签是可选的, 但逆上下文 会基于规范化后的 语言 标签创建条目,从而无论表示形式如何,都可以选择合适的术语。

4.3.2 算法

该算法接受一个必需输入:正在为其创建 逆上下文的 active context。

  1. 将 result 初始化为空映射。
  2. 将 default language 初始化为 @none。 如果 active context 有默认语言, 则将 default language 设置为来自 活动 上下文的默认语言, 并规范化为小写。
  3. 对于 active context 中的每个键术语 和值术语定义, 按最短术语 优先排序(平局时选择字典序最小的 术语):
    1. 如果术语定义是 null, 则术语不能在 压缩期间被选择, 因此继续处理下一个术语。
    2. 将 container 初始化为 @none。 如果容器映射非空,则将 container 设置为容器映射的所有值按字典序排列后的连接结果 。
    3. 将 var 初始化为该IRI 映射的值, 该映射属于术语定义。
    4. 如果 var 不是 result 的条目,则向 result 添加一个条目, 其键为 var,其值 是一个空映射。
    5. 使用变量 container map 引用 result 中与 var 条目关联的值。
    6. 如果 container map 没有 container 条目, 则创建一个,并将其值设置为一个新的 映射,其中包含三个条目。 第一个条目是 @language, 其值是一个新的空 映射;第二个条目是 @type, 其值是一个新的空映射; 第三个条目是 @any, 其值是一个新的映射,其中 @none 条目被设置为正在 处理的术语。
    7. 使用变量 type/language map 引用 container map 中与 container 条目 关联的值。
    8. 使用变量 type map 引用 type/language map 中与 @type 条目关联的值。
    9. 使用变量 language map 引用 type/language map 中与 @language 条目关联的值。
    10. 如果术语定义 表明该术语 表示反向属性:
      1. 如果 type map 没有 @reverse 条目,则创建一个,并 将其值设置为正在处理的 术语。
    11. 否则,如果术语定义具有 一个 类型映射, 且该映射是 @none:
      1. 如果 language map 没有 @any 条目,则创建一个,并 将其值设置为正在处理的 术语。
      2. 如果 type map 没有 @any 条目,则创建一个,并 将其值设置为正在处理的 术语。
    12. 否则,如果术语定义具有 一个 类型映射:
      1. 如果 type map 没有与 术语 定义中的类型 映射相对应的条目, 则创建一个,并将其值设置为正在处理的 术语。
    13. 否则,如果术语定义同时具有 语言 映射和方向映射:
      1. 创建一个新变量 lang dir。
      2. 如果语言映射和方向映射 都不是 null,则将 lang dir 设置为 语言映射和方向映射以下划线("_") 分隔并连接后的结果, 并规范化为小写。
      3. 否则,如果语言映射不是 null, 则将 lang dir 设置为语言映射, 并规范化为小写。
      4. 否则,如果方向映射不是 null, 则将 lang dir 设置为前面带下划线 ("_")的方向映射。
      5. 否则,将 lang dir 设置为 @null。
      6. 如果 language map 没有 lang dir 条目,则创建一个,并 将其值设置为正在处理的 术语。
    14. 否则,如果术语定义具有 一个语言 映射(可以是 null):
      1. 如果语言映射等于 null, 则将 language 设置为 @null;否则 设置为语言映射, 并规范化为小写。
      2. 如果 language map 没有 language 条目, 则创建一个,并将其值设置为正在处理的 术语。
    15. 否则,如果术语定义具有 一个方向 映射(可以是 null):
      1. 如果方向映射等于 null, 则将 direction 设置为 @none;否则 设置为前面带下划线 ("_")的方向映射。
      2. 如果 language map 没有 direction 条目, 则创建一个,并将其值设置为正在处理的 术语。
    16. 否则,如果 active context 有 默认基准 方向:
      1. 初始化一个变量 lang dir, 其值为默认 语言和默认基准 方向以下划线("_") 分隔并连接后的结果, 并规范化为小写。
      2. 如果 language map 没有 lang dir 条目, 则创建一个,并将其值设置为正在处理的 术语。
      3. 如果 language map 没有 @none 条目, 则创建一个,并将其值设置为正在处理的 术语。
      4. 如果 type map 没有 @none 条目, 则创建一个,并将其值设置为正在处理的 术语。
    17. 否则:
      1. 如果 language map 没有 default language 条目 (规范化为小写后), 则创建一个,并将其值设置为正在处理的 术语。
      2. 如果 language map 没有 @none 条目,则创建一个,并 将其值设置为正在处理的 术语。
      3. 如果 type map 没有 @none 条目,则创建一个,并 将其值设置为正在处理的 术语。
  4. 返回 result。

4.4 术语选择

此算法通过 IRI 压缩算法调用, 使用活动上下文的 逆上下文来查找最适合 用于压缩某个 IRI的 术语。还会给出与该 IRI关联的值的其他 信息,包括最适合用于表达该值的 容器 映射 以及类型映射或 语言映射。

4.4.1 概述

本节是非规范性的。

会首先按照首选 容器映射的给定顺序 搜索逆上下文中对应于该 IRI的条目。在具有匹配 容器映射的 术语中, 优先选择具有匹配类型 映射或语言 映射的术语, 而不是没有类型 映射或 语言映射的术语。 如果没有具有匹配术语 的容器 映射,则会选择 没有容器 映射、但匹配给定 类型映射或 语言映射的 术语。如果 仍然没有选中的术语,则在可用时会选择没有 类型映射或 语言映射的 术语。不会选择任何 具有冲突类型 映射或语言 映射的 术语。 具有相同映射的术语之间的 平局会通过先选择最短术语,然后 选择字典序最小的术语来解决。请注意,这些平局会 自动解决,因为它们在先前使用 逆上下文创建算法 创建逆上下文时已经得到解决。

4.4.2 算法

此算法有五个必需输入。它们是: 一个 active context, 一个关键字或 IRI var, 一个数组 containers,表示首选 容器映射的有序列表, 一个字符串 type/language,指示是否 查找具有匹配类型映射 或语言映射的 术语, 以及一个数组,表示 要为类型映射或 语言映射查找的 preferred values有序列表。

  1. 如果 active context 具有 null 逆上下文, 则将 active context 中的逆上下文 设置为使用 active context 调用 逆上下文创建算法 的结果。
  2. 将 inverse context 初始化为 active context 中逆上下文的值。
  3. 将 container map 初始化为 inverse context 中与 var 关联的值。
  4. 对于 containers 中的每一项 container:
    1. 如果 container 不是 container map 的条目,则 没有具有与其匹配的 容器 映射的术语,因此继续处理下一个 container。
    2. 将 type/language map 初始化为 container map 中与 container 条目关联的值。
    3. 将 value map 初始化为 type/language map 中与 type/language 条目关联的值。
    4. 对于 preferred values 中的每个 item:
      1. 如果 item 不是 value map 的条目, 则没有具有匹配 类型 映射或语言映射的 术语, 因此继续处理下一个 item。
      2. 否则,已找到匹配术语,返回 value map 中与 item 条目关联的值。
  5. 未找到匹配术语。返回 null。

4.4.3 示例

本节是非规范性的。

以下示例旨在说明术语选择算法 对不同术语定义和值的行为。它并不全面,而是 旨在说明算法的不同部分。

语言映射术语

如果术语定义具有 "@container": "@language",它只会匹配 没有 @type 的值 对象。

带数据类型的术语

如果术语定义具有数据类型,它只会匹配 具有匹配数据类型的值 对象。

5. 展开算法

以下章节描述用于展开 JSON-LD 文档、IRI 和值的算法。

5.1 展开算法

此算法展开 JSON-LD 文档,使所有上下文 定义被移除,所有术语和 紧凑 IRI被 展开为 IRI、 空白 节点标识符或 关键字,并且所有 JSON-LD 值都以 数组中的展开形式表示。

5.1.1 概述

本节是非规范性的。

从根 element 开始,我们可以递归处理 JSON-LD 文档,直到得到完全 展开的 result。 在 展开 element 时,我们可以根据其类型以不同方式处理 每一种情况,从而分解问题:

  1. 如果 element 是 null,则没有需要 展开的内容。
  2. 否则,如果 element 是标量,则根据 值展开算法展开它。
  3. 否则,如果 element 是数组,则递归展开 其中每一项,并在新的 数组中返回它们。
  4. 否则,element 是映射。我们展开 它的每个条目, 将它们添加到 result,然后递归展开 每个条目的每个值。其中一些条目键会是 术语或 紧凑 IRI, 另一些则会是 关键字,或者 因为它们在上下文中没有定义而被直接忽略。任何 IRI都将使用 IRI 展开算法展开。

最后,在确保 result 位于数组中后, 返回 result。

注

虽然基于 [RDF11-CONCEPTS] 的 数据模型 不支持多个无序属性值, 但此算法不会移除展开期间在无序数组中可能发现的重复项。 其他算法,例如 § 6.1 压缩算法 和 § 7.1 扁平化算法,会从无序数组中消除 重复值。 本规范的未来版本可能会更新为在数组值形成集合时移除重复的 数组值。

5.1.2 算法

该算法接受四个必需和三个可选输入变量。 必需输入是 active context、 active property、要展开的 element, 以及与原始待展开文档的 documentUrl 关联的 base URL。 可选输入是 frameExpansion 标志,它允许用于框架展开的特殊输入形式; ordered 标志,在注明之处用于按字典序排列 映射条目键; 以及 from map 标志,用于控制是否回退 与非传播上下文关联的 活动 上下文中的先前术语定义。 如果未传入,可选标志均设为 false。

该算法还执行特定于展开 JSON-LD 框架的处理步骤。对于框架,@id 和 @type 条目可以接受由 IRI组成的数组或 空映射。值对象的 条目也可以 接受由字符串组成的 数组,或空映射。 成帧还使用额外的关键字条目: (@explicit、@default、 @embed、@explicit、@omitDefault 或 @requireAll),它们会在展开过程中保留。 当 frameExpansion 标志被设置为 true 时,会调用 JSON-LD 框架的特殊处理。

注

如术语 [JSON-LD11] 中所述, 为避免前向兼容性问题,术语不应以 @ 字符开头,因为 JSON-LD 的未来版本可能会引入 额外的关键字。 此算法会像处理任何其他术语一样处理此类术语,即除非它们映射到 IRI,否则会被忽略。 该算法的实现可以考虑提供一个 运行时标志,以便在遇到此类术语时显示警告。

注

不允许使用空术语(""), 因为并非所有编程语言都能处理空 JSON 键。 该算法的实现可以考虑提供一个 运行时标志,以便在遇到此类术语时显示警告。

注

使用空白节点 标识符标注属性已经过时, 并可能在 JSON-LD 的未来版本中移除。 该算法的实现可以考虑提供一个 运行时标志,以便在遇到此类术语时显示警告。

  1. 如果 element 是 null,返回 null。
  2. 如果 active property 是 @default, 将 frameExpansion 标志初始化为 false。
  3. 如果 active property 在 active context 中具有带局部 上下文的术语定义, 则将 property-scoped context 初始化为该局部上下文。
  4. 如果 element 是标量,
    1. 如果 active property 是 null 或 @graph, 通过返回 null 丢弃自由浮动的标量。
    2. 如果定义了 property-scoped context, 则将 active context 设置为 上下文处理算法的结果, 传入 active context、property-scoped context 作为 local context, 以及 active property 在 active context 中的术语定义中的 base URL。
    3. 返回 值展开算法的结果,传入 active context、active property,以及 element 作为 value。
  5. 如果 element 是数组,
    1. 初始化一个空数组 result。
    2. 对于 element 中的每个 item:
      1. 将 expanded item 初始化为递归使用此 算法的结果,传入 active context、 active property、item 作为 element、 base URL、 frameExpansion ordered 和 from map 标志。
      2. 如果 active property 的 容器映射 包含 @list, 并且 expanded item 是 数组, 则将 expanded item 设置为新的 映射,其中包含 @list 条目, 其值为原始的 expanded item。
      3. 如果 expanded item 是数组,将其每一项追加到 result。否则,如果 expanded item 不是 null,则将其追加到 result。
    3. 返回 result。
  6. 否则,element 是映射。
  7. 如果 active context 具有 先前上下文, 则 active context 不会传播。 如果 from map 未定义或为 false, 并且 element 不包含展开为 @value 的 条目, 且 element 也不只由单个展开为 @id 的 条目组成 (其中条目会被 IRI 展开), 则将 active context 设置为 active context 中的 先前上下文, 因为术语作用域上下文的作用域在处理新的 节点对象时不适用。
  8. 如果定义了 property-scoped context, 则将 active context 设置为 上下文处理算法的结果, 传入 active context、property-scoped context 作为 local context、 active property 在 active context 中的术语定义中的 base URL 以及 true 作为 override protected。
  9. 如果 element 包含 @context 条目,则将 active context 设置为 上下文处理算法的结果, 传入 active context、@context 条目的值作为 local context 以及 base URL。
  10. 将 type-scoped context 初始化为 active context。 这用于展开可能与任何先前 类型作用域上下文相关的值。
  11. 对于 element 中每个 key 和 value, 按 key 字典序排列, 其中 key IRI 展开为 @type:
    1. 如果需要,将 value 转换为数组。
    2. 对于按字典序排列的 value 的每个值 term, 如果 term 是字符串, 并且 type-scoped context 中 term 的术语定义 具有局部上下文,则将 active context 设置为 上下文处理算法的结果, 传入 active context、 term 的 局部上下文的值作为 local context、 active context 中 value 的术语定义中的 base URL, 以及 false 作为 propagate。
  12. 初始化两个空映射,result 和 nests。 将 input type 初始化为 element 中第一个 展开为 @type 的条目的最后一个值的展开结果 (如有),按键的字典序排列条目。 匹配条目的键和值都会被 IRI 展开。
  13. 对于 element 中的每个 key 和 value, 如果 ordered 为 true,则按 key 字典序排列:
    1. 如果 key 是 @context,继续处理 下一个 key。
    2. 将 expanded property 初始化为 IRI 展开 key 的结果。
    3. 如果 expanded property 是 null,或者它既 不包含冒号(:)也不是关键字, 则通过继续处理下一个 key 来丢弃 key。
    4. 如果 expanded property 是关键字:
      1. 如果 active property 等于 @reverse,则 检测到 invalid reverse property map 错误,并中止处理。
      2. 如果 result 已经有一个 expanded property 条目, 且该条目不是 @included 或 @type (除非处理 模式是 json-ld-1.0), 则检测到 colliding keywords 错误,并中止处理。
      3. 如果 expanded property 是 @id:
        1. 如果 value 不是字符串, 则检测到 invalid @id value 错误,并中止处理。 当 frameExpansion 标志被设置时,value MAY 是空映射,或由一个 或多个字符串组成的 数组。
        2. 否则, 将 expanded value 设置为 使用 true 作为 document relative 且使用 false 作为 vocab 对 value 进行 IRI 展开的结果。 当 frameExpansion 标志被设置时,expanded value 将是 由一个或多个值组成的数组,其中字符串 值使用上述 IRI 展开算法展开。
      4. 如果 expanded property 是 @type:
        1. 如果 value 既不是字符串, 也不是由 字符串组成的 数组, 则检测到 invalid type value 错误,并中止处理。 当 frameExpansion 标志被设置时,value MAY 是空映射,或 默认 对象, 其中 @default 的值被限制为 IRI。 所有其他值都表示已检测到 invalid type value 错误,并中止处理。
        2. 如果 value 是空映射,则将 expanded value 设置为 value。
        3. 否则,如果 value 是默认 对象,则将 expanded value 设置为 新的默认 对象,其中 @default 的值设置 为使用 type-scoped context 作为 active context 并使用 true 作为 document relative 对 value 进行 IRI 展开的结果。
        4. 否则, 将 expanded value 设置为 使用 type-scoped context 作为 active context 并使用 true 作为 document relative 对其每个值进行 IRI 展开 的结果。
        5. 如果 result 已经有 @type 条目, 则将 result 中 @type 的值前置到 expanded value, 如有必要,将其转换为数组。
          注
          不隐含从字符串 value 到数组 expanded value 的转换,并且 value 的形式 应在 expanded value 中保留。
      5. 如果 expanded property 是 @graph,则将 expanded value 设置为递归使用此算法的结果,传入 active context、@graph 作为 active property、value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志, 并确保 expanded value 是由一个或多个映射组成的 数组。
      6. 如果 expanded property 是 @included:
        1. 如果处理 模式是 json-ld-1.0, 继续处理 element 中的下一个 key。
        2. 将 expanded value 设置为 递归使用 此算法的结果,传入 active context、 null 作为 active property、 value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志, 并确保结果是数组。
        3. 如果 expanded value 的任一元素不是节点 对象, 则检测到 invalid @included value 错误,并中止处理。
        4. 如果 result 已经有 @included 条目, 则将 result 中 @included 的值前置到 expanded value。
      7. 如果 expanded property 是 @value:
        1. 如果 input type 是 @json, 将 expanded value 设置为 value。 如果处理 模式是 json-ld-1.0, 则检测到 invalid value object value 错误,并中止处理。
        2. 否则,如果 value 既不是标量 也不是 null, 则检测到 invalid value object value 错误,并中止处理。 当 frameExpansion 标志被设置时,value MAY 是空映射,或由 标量 值组成的数组。
        3. 否则,将 expanded value 设置为 value。 当 frameExpansion 标志被设置时, expanded value 将是由一个或 多个字符串 值组成的 数组, 或是包含空映射的 数组。
        4. 如果 expanded value 是 null,则将 result 的 @value 条目设置为 null,并继续处理 element 中的下一个 key。在这种情况下需要保留 Null 值,因为 @type 条目的含义取决于 @value 条目是否存在。
      8. 如果 expanded property 是 @language:
        1. 如果 value 不是字符串, 则检测到 invalid language-tagged string 错误,并中止处理。 当 frameExpansion 标志被设置时,value MAY 是空映射,或由零个或多个 字符串组成的数组。
        2. 否则,将 expanded value 设置为 value。 如果 value 按照 [BCP47] 的 第 2.2.9 节 不是格式良好的, 处理器 SHOULD 发出 警告。 当 frameExpansion 标志被设置时, expanded value 将是由一个或 多个字符串 值组成的 数组, 或是包含空映射的 数组。
          注
          处理器 MAY 将语言 标签规范化为小写。
      9. 如果 expanded property 是 @direction:
        1. 如果处理 模式是 json-ld-1.0, 继续处理 element 中的下一个 key。
        2. 如果 value 既不是 "ltr" 也不是 "rtl",则检测到 invalid base direction 错误,并中止处理。 当 frameExpansion 标志被设置时,value MAY 是空映射,或由零个或多个 字符串组成的数组。
        3. 否则,将 expanded value 设置为 value。 当 frameExpansion 标志被设置时, expanded value 将是由一个或多个 字符串 值组成的 数组, 或是包含空映射的 数组。
      10. 如果 expanded property 是 @index:
        1. 如果 value 不是字符串, 则检测到 invalid @index value 错误,并中止处理。
        2. 否则, 将 expanded value 设置为 value。
      11. 如果 expanded property 是 @list:
        1. 如果 active property 是 null 或 @graph,继续处理 element 中的下一个 key 以移除自由浮动的列表。
        2. 否则,将 expanded value 初始化为 递归使用此算法的结果,传入 active context、 active property、value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志, 并确保结果是数组。
      12. 如果 expanded property 是 @set,则将 expanded value 设置为递归使用此算法的结果, 传入 active context、 active property、value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志。
      13. 如果 expanded property 是 @reverse:
        1. 如果 value 不是映射,则检测到 invalid @reverse value 错误,并中止处理。
        2. 否则,将 expanded value 初始化为递归使用 此 算法的结果,传入 active context、 @reverse 作为 active property、 value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志。
        3. 如果 expanded value 包含 @reverse 条目, 即属性 被反转了两次,则对其每个 property 和 item 执行以下步骤:
          1. 使用添加值将 item 添加到 result 中 property 条目, 使用 true 作为 as array。
        4. 如果 expanded value 包含除 @reverse 之外的条目:
          1. 将 reverse map 设置为 result 中 @reverse 条目的值, 如有必要,将其初始化为空映射。
          2. 对于 expanded value 中 除 @reverse 之外的每个 property 和 items:
            1. 对于 items 中的每个 item:
              1. 如果 item 是值 对象或列表 对象,则检测到 invalid reverse property value 错误,并中止处理。
              2. 使用添加 值将 item 添加到 reverse map 中 property 条目, 使用 true 作为 as array。
        5. 继续处理 element 中的下一个 key。
      14. 如果 expanded property 是 @nest, 将 key 添加到 nests,如有必要将其初始化为空数组。 继续处理 element 中的下一个 key。
      15. 当 frameExpansion 标志被设置时, 如果 expanded property 是任何其他 成帧关键字(@default、 @embed、@explicit、@omitDefault 或 @requireAll), 则将 expanded value 设置为递归执行 展开算法的结果, 传入 active context、 active property、value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志。
      16. 除非 expanded value 是 null, expanded property 是 @value, 并且 input type 不是 @json, 否则将 result 的 expanded property 条目设置为 expanded value。
      17. 继续处理 element 中的下一个 key。
    5. 将 container mapping 初始化为 active context 中 key 的容器 映射。
    6. 如果 active context 中 key 的术语定义 具有 @json 的类型 映射, 则将 expanded value 设置为新的映射,将 @value 条目设置为 value,并将 @type 条目设置为 @json。
    7. 否则,如果 container mapping 包含 @language,并且 value 是映射,则 value 按如下方式从语言映射 展开:
      1. 将 expanded value 初始化为空 数组。
      2. 将 direction 初始化为 active context 中的 默认基准 方向。
      3. 如果 活动 上下文中 key 的术语 定义 具有方向映射, 则用该值更新 direction。
      4. 对于 value 中的每个键值对 language-language value, 如果 ordered 为 true,则按 language 字典序排列:
        1. 如果 language value 不是数组, 将 language value 设置为只包含 language value 的数组。
        2. 对于 language value 中的每个 item:
          1. 如果 item 是 null, 继续处理 language value 中的下一个条目。
          2. item 必须是字符串, 否则检测到 invalid language map value 错误,并中止处理。
          3. 初始化一个新的映射 v, 它由两个 键值对组成:(@value-item) 和 (@language-language)。 如果 item 既不是 @none,也不是按照 [BCP47] 的 第 2.2.9 节格式良好, 处理器 SHOULD 发出警告。
            注
            处理器 MAY 将语言 标签规范化为小写。
          4. 如果 language 是 @none, 或展开为 @none,则从 v 中移除 @language。
          5. 如果 direction 不是 null, 则向 v 添加一个 @direction 的条目, 其值为 direction。
          6. 将 v 追加到 expanded value。
    8. 否则,如果 container mapping 包含 @index、 @type 或 @id,并且 value 是映射,则 value 按如下方式从映射展开:
      1. 将 expanded value 初始化为空数组。
      2. 将 index key 初始化为 活动 上下文中 key 的 索引映射, 或如果不存在,则为 @index。
      3. 对于 value 中的每个键值对 index-index value, 如果 ordered 为 true,则按 index 字典序排列:
        1. 如果 container mapping 包含 @id 或 @type, 则将 map context 初始化为 active context 中的 先前上下文 (如果存在), 否则将 map context 设置为 active context。
        2. 如果 container mapping 包含 @type, 且 index 在 map context 中的术语 定义具有局部 上下文,则将 map context 更新为 上下文处理 算法的结果, 传入 map context 作为 active context, index 的局部 上下文的值 作为 local context, 以及 map context 中 index 的术语 定义中的 base URL。
        3. 否则,将 map context 设置为 active context。
        4. 将 expanded index 初始化为 IRI 展开 index 的结果。
        5. 如果 index value 不是数组, 则将 index value 设置为只包含 index value 的数组。
        6. 将 index value 初始化为 使用此算法递归处理的结果,传入 map context 作为 active context、 key 作为 active property、 index value 作为 element、 base URL、 true 作为 from map, 以及 frameExpansion 和 ordered 标志。
        7. 对于 index value 中的每个 item:
          1. 如果 container mapping 包含 @graph, 且 item 不是图 对象, 则将 item 设置为新的映射, 其中包含键值对 @graph-item, 并确保该值使用数组表示。
          2. 如果 container mapping 包含 @index, index key 不是 @index, 且 expanded index 不是 @none:
            1. 将 re-expanded index 初始化为调用 值展开 算法的结果, 传入 active context、 index key 作为 active property, 以及 index 作为 value。
            2. 将 expanded index key 初始化为 IRI 展开 index key 的结果。
            3. 将 index property values 初始化为 一个数组, 由 re-expanded index 后跟 item 中 expanded index key 的 连接结果的现有值(如有)组成。
            4. 将键值对(expanded index key-index property values) 添加到 item。
            5. 如果 item 是值对象, 它 MUST NOT 包含任何额外属性; 已检测到 invalid value object 错误,并中止处理。
          3. 否则,如果 container mapping 包含 @index, item 没有 @index 条目, 且 expanded index 不是 @none, 则将键值对(@index-index)添加到 item。
          4. 否则,如果 container mapping 包含 @id, item 没有 @id 条目, 且 expanded index 不是 @none, 则将键值对(@id-expanded index)添加到 item, 其中 expanded index 被设置为使用 true 作为 document relative 且使用 false 作为 vocab 对 index 进行 IRI 展开的结果。
          5. 否则,如果 container mapping 包含 @type 且 expanded index 不是 @none, 则将 types 初始化为一个新的数组, 由 expanded index 后跟 item 中 @type 的任何现有值组成。 将键值对(@type-types)添加到 item。
          6. 将 item 追加到 expanded value。
    9. 否则,将 expanded value 初始化为 递归使用此算法的结果,传入 active context、 key 作为 active property、value 作为 element、 base URL, 以及 frameExpansion 和 ordered 标志。
    10. 如果 expanded value 是 null,则通过继续处理 element 中的下一个 key 来忽略 key。
    11. 如果 container mapping 包含 @list 且 expanded value 尚不是列表对象, 则将 expanded value 转换为列表对象: 先在其尚不是数组时,将其设置为只包含 expanded value 的数组, 然后将其设置为包含 键值对 @list-expanded value 的映射。
    12. 如果 container mapping 包含 @graph, 且既不包含 @id 也不包含 @index, 则在必要时将 expanded value 转换为数组, 然后将 expanded value 中的每个值 ev 转换为 图 对象:
      1. 通过创建一个包含键值对 @graph-ev 的映射,将 ev 转换为 图对象, 其中 ev 表示为数组。
        注
        如果 ev 已经是图 对象形式, 这可能导致一个图 对象包含另一个图 对象。
    13. 如果与 key 关联的术语定义 表明它是反向属性
      1. 如果 result 没有 @reverse 条目,则创建 一个,并将其值初始化为空映射。
      2. 使用变量 reverse map 引用 result 中 @reverse 条目的值。
      3. 如果 expanded value 不是数组,则将 它设置为包含 expanded value 的数组。
      4. 对于 expanded value 中的每个 item
        1. 如果 item 是值 对象或列表 对象,则检测到 invalid reverse property value 错误,并中止处理。
        2. 如果 reverse map 没有 expanded property 条目, 则创建一个,并将其值初始化为空数组。
        3. 使用添加值将 item 添加到 reverse map 中的 expanded property 条目, 使用 true 作为 as array。
    14. 否则,key 不是反向属性, 使用添加值将 expanded value 添加到 result 中的 expanded property 条目, 使用 true 作为 as array。
  14. 对于 nests 中的每个键 nesting-key, 如果 ordered 为 true,则按字典序排列:
    1. 将 nested values 初始化为 element 中 nesting-key 的值,并确保它是数组。
    2. 对于 nested values 中的每个 nested value:
      1. 如果 nested value 不是映射,或 nested value 中的任何键展开为 @value,则检测到 invalid @nest value 错误, 并中止处理。
      2. 递归重复步骤 13 和 14, 使用 nested value 作为 element。
        注
        通过在 nested value 上调用步骤 13 和 14, 我们能够展开任意层级的嵌套,并将结果 合并到 result 中。 步骤 13 遍历 nested value 中的每个条目并展开它,同时收集 每一层发现的新的 nested values,直到所有嵌套都被 提取出来。
  15. 如果 result 包含 @value 条目:
    1. result 不得包含除 @direction、 @index、 @language、 @type 和 @value 之外的任何条目。 如果它包含 @language 或 @direction 条目中的任意一个, 则不得包含 @type 条目。 否则,检测到 invalid value object 错误,并中止处理。
    2. 如果 result 的 @type 条目 是 @json,则 @value 条目可以 包含任意值,并被视为JSON 字面量。
    3. 否则,如果 result 的 @value 条目的值是 null,或空数组,返回 null。
    4. 否则,如果 result 的 @value 条目的值 不是字符串,并且 result 包含 @language 条目, 则检测到 invalid language-tagged value 错误(只有字符串 可以带语言标签),并中止处理。
    5. 否则,如果 result 具有 @type 条目, 且其值不是IRI,则检测到 invalid typed value 错误,并中止处理。
  16. 否则,如果 result 包含 @type 条目 且其关联值不是数组,则将其设置为 只包含该关联值的数组。
  17. 否则,如果 result 包含 @set 或 @list 条目:
    1. result 最多只能包含一个其他条目, 且该条目必须是 @index。否则,检测到 invalid set or list object 错误,并中止处理。
    2. 如果 result 包含 @set 条目,则 将 result 设置为该条目的关联值。
  18. 如果 result 是只包含 @language 条目的 映射,则返回 null。
  19. 如果 active property 是 null 或 @graph, 按如下方式丢弃自由浮动值:
    1. 如果 result 是空的映射, 或只包含 @value 或 @list 条目, 则将 result 设置为 null。
    2. 否则,如果 result 是映射,其唯一 条目是 @id,则将 result 设置为 null。 当 frameExpansion 标志被设置时, 只包含 @id 条目的映射 会被保留。
  20. 返回 result。

5.2 IRI 展开

在 JSON-LD 文档中,一些键和值可能表示 IRI。本节 定义一种算法,用于将表示 字符串的 IRI 转换为 绝对 IRI 或空白节点标识符。 它还涵盖将关键字别名 转换为关键字。

IRI 展开可能发生在上下文 处理期间,也可能发生在 任何其他 JSON-LD 算法期间。如果 IRI 展开发生在上下文 处理期间,则会将局部上下文及其相关的 defined 映射从上下文处理算法 传递给此算法。这允许通过 创建术语定义算法处理 术语定义 依赖项。

5.2.1 概述

本节是非规范性的。

为了将 value 展开为IRI,我们必须 首先确定它是 null、术语、 关键字别名, 还是某种形式的IRI。根据所发现的内容, 我们处理特定类型的展开;例如,我们将 关键字别名展开为关键字,并根据 活动 上下文中IRI 映射, 将术语 展开为IRI。 在检查 value 时,我们 还可能发现需要创建术语定义 依赖项,因为我们正在上下文处理期间运行此算法。 我们可以通过检查局部 上下文是否为 null, 来判断是否正在上下文处理期间运行。 当 value 是局部上下文中的 条目, 并且 defined 映射 没有针对 value 的条目且其关联值为 true 时,我们知道需要在 活动 上下文中创建术语定义。 defined 映射在 上下文处理期间用于跟踪 哪些术语已经 被定义,或正在 被定义过程中。我们通过使用 创建术语定义算法来创建 术语 定义。

注

具有关键字形式、 但不是关键字的值(即它们以 "@" 开头)不会 映射到任何值,因为它们保留供将来使用。 该算法返回 null,以便在遇到它们时将其忽略。

5.2.2 算法

该算法接受两个必需输入变量和四个可选输入变量。必需 输入是 active context 和要展开的 value。 可选输入是两个标志: document relative 和 vocab,它们指定 value 是否可以分别相对于文档的基准 IRI或 活动上下文的 词汇表 映射, 将 value 解释为相对 IRI 引用; 以及一个 local context 和一个映射 defined,供 此算法在上下文处理期间使用。 如果未传入,这两个标志被设置为 false, local context 和 defined 被初始化为 null。

  1. 如果 value 是关键字或 null, 原样返回 value。
  2. 如果 value 具有关键字形式 (即它匹配 [RFC5234] 中的 ABNF 规则 "@"1*ALPHA), 处理器 SHOULD 生成警告并返回 null。
  3. 如果 local context 不是 null,它包含 键等于 value 的条目, 并且 defined 中 value 对应 条目的值不是 true, 调用创建术语定义算法, 传入 active context、local context、 value 作为 term,以及 defined。这将确保在 上下文处理期间,为 active context 中的 value 创建 术语 定义。
  4. 如果 active context 对 value 有术语定义,且关联的 IRI 映射是关键字, 返回该关键字。
  5. 如果 vocab 是 true,并且 active context 对 value 有术语定义,则返回关联的 IRI 映射。
  6. 如果 value 在第一个字符之后的 任意位置包含冒号(:), 它要么是 IRI,要么是紧凑 IRI,要么是 空白节点 标识符:
    1. 在第一次出现冒号(:)的位置,将 value 拆分为 prefix 和 suffix。
    2. 如果 prefix 是下划线(_), 或 suffix 以前置双斜杠 (//)开头,则原样返回 value,因为它已经是 IRI或空白节点 标识符。
    3. 如果 local context 不是 null,它 包含 prefix 条目,且 defined 中 prefix 条目的值 不是 true,则调用 创建术语定义算法, 传入 active context、 local context、prefix 作为 term, 以及 defined。这将确保在 上下文处理期间,为 active context 中的prefix创建 术语 定义。
    4. 如果 active context 包含 prefix 的术语定义, 且具有非 null 的IRI 映射, 并且该术语定义的 前缀 标志为 true, 则返回与 prefix 关联的 IRI 映射 和 suffix 连接后的结果。
    5. 如果 value 具有 形式为 IRI的形式, 返回 value。
  7. 如果 vocab 是 true,并且 active context 有词汇表映射, 返回将该词汇表映射 与 value 连接的结果。
  8. 否则,如果 document relative 是 true, 将 value 设置为相对于 active context 中的基准 IRI 解析 value 的结果。仅使用 [RFC3986] 的 第 5.2 节中的基本算法; 不执行 基于语法的规范化或 基于方案的规范化。 按照 [RFC3987] 的 第 6.5 节, IRI 引用中额外允许的字符 与 URI 引用中非保留字符的处理方式相同。
  9. 原样返回 value。

5.3 值展开

JSON-LD 中的一些值可以用 紧凑形式表示。在处理 JSON-LD 文档时,有时需要将这些值 展开。 应用此算法后,称一个值处于展开 形式。

5.3.1 概述

本节是非规范性的。

如果活动属性在 活动 上下文中有设置为 @id 或 @vocab 的 类型映射, 且值是字符串, 则返回一个具有单个 @id 条目的映射, 该条目的值是对 value 使用 IRI 展开 算法得到的结果。

否则,结果将是一个包含 @value 条目的映射, 其值是传入的 value。 此外,如果存在与活动属性关联的 类型映射, 则会包含一个 @type 条目;或者如果 value 是 字符串,且存在与 活动 属性关联的语言映射, 则会包含一个 @language 条目。

请注意,被解释为IRI的值分为两类: 一类是 document relative,另一类是 相对于词汇表。属性和 @type 的值, 以及标记为 "@type": "@vocab" 的术语, 都是相对于词汇表的,这意味着它们需要是 已定义的术语、一个紧凑 IRI (其中前缀是 术语), 或者是一个使用 词汇表映射转换为 IRI的字符串。

5.3.2 算法

该算法接受三个必需输入:active context、 active property,以及要展开的 value。

  1. 如果 active property 在 active context 中具有 @id 的类型映射, 且 value 是字符串, 则返回一个新的 映射,其中包含一个 条目,其键为 @id,其值为 使用 true 作为 document relative 且使用 false 作为 vocab 对 value 进行 IRI 展开的结果。
  2. 如果 active property 在 active context 中具有 @vocab 的类型映射, 且 value 是字符串, 则返回一个新的 映射,其中包含一个 条目,其键为 @id,其值为 使用 true 作为 document relative 对 value 进行 IRI 展开的结果。
  3. 否则,将 result 初始化为一个映射, 其中 @value 条目的值被设置为 value。
  4. 如果 active property 在 active context 中具有 除 @id、@vocab 或 @none 之外的 类型映射, 则将 @type 添加到 result,并将其值设置为与 类型映射关联的值。
  5. 否则,如果 value 是字符串:
    1. 将 language 初始化为 active context 中 active property 的语言映射(如有), 否则初始化为 active context 的 默认语言。
    2. 将 direction 初始化为 active context 中 active property 的方向映射(如有), 否则初始化为 active context 的默认基准 方向。
    3. 如果 language 不是 null, 则向 result 添加 @language,其值为 language。
    4. 如果 direction 不是 null, 则向 result 添加 @direction,其值为 direction。
  6. 返回 result。

6. 压缩算法

以下章节描述用于压缩 JSON-LD 文档、IRI 和值的算法。

6.1 压缩算法

此算法压缩 JSON-LD 文档,以便应用给定的 上下文。这 必须导致将 任何适用的 IRI 缩短为 术语或 紧凑 IRI,将任何 适用的 关键字缩短为 关键字别名,并将 任何以展开形式表示的适用 JSON-LD 值 转换为简单值,例如 字符串或 数字。

6.1.1 概述

本节是非规范性的。

从根 element 开始,我们可以递归处理 JSON-LD 文档,直到得到完全 压缩的 result。 在 压缩 element 时,我们可以根据其类型以不同方式处理 每一种情况,从而分解问题:

  1. 如果 element 是标量,它已经处于 压缩 形式,因此我们直接返回它。
  2. 如果 element 是数组,我们递归压缩 其中每一项,并在新的 数组中返回它们。
  3. 否则 element 是映射。element 中每个 条目的值都会被递归压缩。 一些条目键会使用 IRI 压缩算法 压缩为术语或紧凑 IRI, 另一些则会从关键字压缩为 关键字别名,或者 因为它们在上下文中没有定义而保持 不变。 值会通过 值压缩算法转换为 压缩形式。一些数据 会根据上下文中指定的容器映射进行重塑, 例如 @index 或 @language 映射。

6.1.2 算法

该算法接受三个必需和两个可选输入变量。 必需输入是 active context、 active property 和要压缩的 element。 可选输入是 compactArrays 标志 和 ordered 标志,用于在注明之处按字典序排列 映射条目键。 如果未传入,两个标志均设置为 false。

  1. 将 type-scoped context 初始化为 active context。 这用于压缩可能与任何先前 类型作用域上下文相关的值。
  2. 如果 element 是标量,它已经处于其 最 紧凑形式,因此直接返回 element。
  3. 如果 element 是数组:
    1. 将 result 初始化为空数组。
    2. 对于 element 中的每个 item:
      1. 将 compacted item 初始化为递归使用此 算法的结果,传入 active context、 active property、 item 作为 element, 以及 compactArrays 和 ordered 标志。
      2. 如果 compacted item 不是 null,则将 它追加到 result。
    3. 如果 result 为空或包含多于一个值, 或 compactArrays 为 false, 或 active property 是 @graph 或 @set, 或 active context 中 active property 的 容器映射包含 @list 或 @set, 返回 result。
    4. 否则,返回 result 中的值。
  4. 否则 element 是映射。
  5. 如果 active context 具有先前上下文, 则 active context 不会传播。 如果 element 不包含 @value 条目, 且 element 也不只由单个 @id 条目组成, 则将 active context 设置为来自 active context 的 先前上下文, 因为术语作用域上下文的作用域在处理新的 节点对象时不适用。
  6. 如果 active context 中 active property 的术语定义 具有局部 上下文:
    1. 将 active context 设置为 上下文处理算法的结果, 传入 active context、 active property 的局部上下文的值作为 local context, active context 中 active property 的 术语定义中的 base URL, 以及 true 作为 override protected。
  7. 如果 element 具有 @value 或 @id 条目,且使用 值压缩算法的结果 (传入 active context、 active property,以及 element 作为 value) 是标量, 或者 active property 的 术语定义 具有 @json 的类型映射, 则返回该结果。
  8. 如果 element 是 列表对象, 且 active context 中 active property 的容器 映射包含 @list, 则返回递归使用此算法的结果,传入 active context、 active property、element 中 @list 的值作为 element, 以及 compactArrays 和 ordered 标志。
  9. 如果 active property 等于 @reverse, 将 inside reverse 初始化为 true, 否则初始化为 false。
  10. 将 result 初始化为空映射。
  11. 如果 element 具有 @type 条目, 创建一个新数组 compacted types,通过将该 条目中的每个 expanded type 通过对 expanded type 进行 IRI 压缩转换为其压缩形式来初始化。 然后,对于按字典序排列的 compacted types 中的每个 term:
    1. 如果 type-scoped context 中 term 的术语定义具有 局部 上下文, 则将 active context 设置为 上下文处理算法的结果, 传入 active context 和 type-scoped context 中 term 的 局部 上下文的值作为 local context type-scoped context 中 term 的 术语定义中的 base URL, 以及 false 作为 propagate。
  12. 对于 element 中的每个键 expanded property 和值 expanded value, 如果 ordered 为 true,则按 expanded property 字典序排列:
    1. 如果 expanded property 是 @id:
      1. 如果 expanded value 是字符串, 则通过 对 expanded value 进行 IRI 压缩 并将 vocab 设置为 false 初始化 compacted value。
      2. 通过 对 expanded property 进行 IRI 压缩 初始化 alias。
      3. 向 result 添加一个 alias 条目,其值 设置为 compacted value,并继续处理下一个 expanded property。
    2. 如果 expanded property 是 @type:
      1. 如果 expanded value 是字符串, 则通过 使用 type-scoped context 作为 active context 对 expanded value 进行 IRI 压缩 初始化 compacted value。
      2. 否则,expanded value 必须是 @type 数组:
        1. 将 compacted value 初始化为空 数组。
        2. 对于 expanded value 中的每一项 expanded type:
          1. 通过 使用 type-scoped context 作为 active context 对 expanded type 进行 IRI 压缩 设置 term。
          2. 将 term 追加到 compacted value。
      3. 通过 对 expanded property 进行 IRI 压缩 初始化 alias。
      4. 如果处理 模式为 json-ld-1.1,且 active context 中 alias 的 容器映射包含 @set, 则将 as array 初始化为 true, 否则初始化为 compactArrays的否定。
      5. 使用添加值将 compacted value 添加到 result 中的 alias 条目, 使用 as array。
      6. 继续处理下一个 expanded property。
    3. 如果 expanded property 是 @reverse:
      1. 将 compacted value 初始化为递归使用此 算法的结果,传入 active context、 @reverse 作为 active property、expanded value 作为 element, 以及 compactArrays 和 ordered 标志。
      2. 对于 compacted value 中的每个 property 和 value:
        1. 如果 active context 中 property 的 术语 定义表明 property 是 反向属性
          1. 如果 active context 中 property 的容器 映射包含 @set, 则将 as array 初始化为 true, 否则初始化为 compactArrays的否定。
          2. 使用添加值将 value 添加到 result 中的 property 条目, 使用 as array。
          3. 从 compacted value 中移除 property 条目。
      3. 如果 compacted value 仍有一些 映射条目,即 它不是空映射:
        1. 通过 对 @reverse 进行 IRI 压缩 初始化 alias。
        2. 将 result 的 alias 条目的值设置为 compacted value。
      4. 继续处理 element 中的下一个 expanded property。
    4. 如果 expanded property 是 @preserve 则:
      1. 将 compacted value 初始化为递归使用此 算法的结果,传入 active context、 active property、 expanded value 作为 element, 以及 compactArrays 和 ordered 标志。
      2. 除非 expanded value 是空数组, 否则将 compacted value 作为 result 中 @preserve 的值添加。
    5. 如果 expanded property 是 @index,并且 active property 在 active context 中具有 包含 @index 的容器映射, 则压缩结果将位于 @index 容器中,通过继续处理下一个 expanded property 来丢弃 @index 条目。
    6. 否则,如果 expanded property 是 @direction、 @index、 @language 或 @value:
      1. 通过 对 expanded property 进行 IRI 压缩 初始化 alias。
      2. 向 result 添加一个 alias 条目,其值 设置为 expanded value,并继续处理下一个 expanded property。
    7. 如果 expanded value 是空数组:
      1. 通过 使用 expanded value 作为 value 且使用 inside reverse 作为 reverse 对 expanded property 进行 IRI 压缩 初始化 item active property。
      2. 如果 active context 中 item active property 的术语 定义具有嵌套值 条目(nest term):
        1. 如果 nest term 不是 @nest, 也不是 active context 中展开为 @nest 的 术语, 则检测到 invalid @nest value 错误,并中止处理。
        2. 如果 result 没有 nest term 条目, 则将其初始化为空映射。
        3. 将 nest result 初始化为 result 中 nest term 的值。
      3. 否则,将 nest result 初始化为 result。
      4. 使用添加值将空数组 添加到 nest result 中的 item active property 条目, 使用 true 作为 as array。
    8. 此时,由于 展开算法, expanded value 必须是 数组。 对于 expanded value 中的每一项 expanded item:
      1. 通过 使用 expanded item 作为 value 且使用 inside reverse 作为 reverse 对 expanded property 进行 IRI 压缩 初始化 item active property。
      2. 如果 active context 中 item active property 的术语 定义具有嵌套值 条目(nest term):
        1. 如果 nest term 不是 @nest, 也不是 active context 中展开为 @nest 的 术语, 则检测到 invalid @nest value 错误,并中止处理。
        2. 如果 result 没有 nest term 条目, 则将其初始化为空映射。
        3. 将 nest result 初始化为 result 中 nest term 的值。
      3. 否则,将 nest result 初始化为 result。
      4. 将 container 初始化为 active context 中 item active property 的 容器映射, 或者如果没有这样的容器映射,则初始化为新的空 数组。
      5. 如果 container 包含 @set, 或 item active property 是 @graph 或 @list, 则将 as array 初始化为 true, 否则初始化为 compactArrays的否定。
      6. 将 compacted item 初始化为 使用 此算法递归处理的结果,传入 active context、 item active property 作为 active property、 expanded item 作为 element, 以及 compactArrays 和 ordered 标志。 如果 expanded item 是列表对象或 图对象, 则分别使用 @list 或 @graph 条目的值作为 element, 而不是 expanded item。
      7. 如果 expanded item 是列表对象:
        1. 如果 compacted item 不是数组, 则将 compacted item 设置为只包含 compacted item 的数组。
        2. 如果 container 不包含 @list:
          1. 将 compacted item 转换为 列表 对象,方法是将其设置为一个 映射, 其中包含一个 条目, 其键是对 @list 进行 IRI 压缩的结果, 其值是原始 compacted item。
          2. 如果 expanded item 包含 @index-value 条目, 则向 compacted item 添加一个 条目, 其键是对 @index 进行 IRI 压缩的结果, 其值是 value。
          3. 使用添加值将 compacted item 添加到 nest result 中的 item active property 条目, 使用 as array。
        3. 否则,将 nest result 中 item active property 条目的值 设置为 compacted item。
      8. 如果 expanded item 是图对象:
        1. 如果 container 包含 @graph 和 @id:
          1. 将 map object 初始化为 nest result 中 item active property 的值, 如有必要,将其初始化为新的空映射。
          2. 通过 对 expanded item 中 @id 的值进行 IRI 压缩 来初始化 map key; 如果不存在这样的值,则为 @none; 如果 expanded item 中有 @id 条目, 则将 vocab 设置为 false。
          3. 使用添加值将 compacted item 添加到 map object 中的 map key 条目, 使用 as array。
        2. 否则,如果 container 包含 @graph 和 @index, 并且 expanded item 是简单 图对象:
          1. 将 map object 初始化为 nest result 中 item active property 的值, 如有必要,将其初始化为新的空映射。
          2. 将 map key 初始化为 expanded item 中 @index 的值, 或者如果不存在这样的值,则为 @none。
          3. 使用添加值将 compacted item 添加到 map object 中的 map key 条目, 使用 as array。
        3. 否则,如果 container 包含 @graph 且 expanded item 是简单 图对象, 该值不能表示为映射对象。
          1. 如果 compacted item 是包含多个值的数组, 则它不能被直接表示, 因为多个对象会被解释为不同的命名图。 将 compacted item 设置为新的映射, 其中包含来自对 @included 进行 IRI 压缩所得的键 和作为值的原始 compacted item。
          2. 使用添加值将 compacted item 添加到 nest result 中的 item active property 条目, 使用 as array。
        4. 否则,container 不包含 @graph, 或者不匹配前述任一情况。
          1. 将 compacted item 设置为新的映射,其中包含 通过对 @graph 进行 IRI 压缩所得的键, 并使用原始 compacted item 作为值。
          2. 如果 expanded item 包含 @id 条目, 则在 compacted item 中添加一个条目,其键 来自对 @id 进行 IRI 压缩, 其值 使用对 expanded item 中 @id 的值进行 IRI 压缩 并使用 false 作为 vocab。
          3. 如果 expanded item 包含 @index 条目, 则在 compacted item 中添加一个条目,其键 来自对 @index 进行 IRI 压缩, 其值为 expanded item 中 @index 的值。
          4. 使用添加值将 compacted item 添加到 nest result 中的 item active property 条目, 使用 as array。
      9. 否则,如果 container 包含 @language、 @index、@id 或 @type 且 container 不包含 @graph:
        1. 将 map object 初始化为 nest result 中 item active property 的值, 如有必要,将其初始化为新的空映射。
        2. 通过 IRI 压缩 @language、@index、@id 或 @type 之一, 基于 container 的内容初始化 container key。
        3. 将 index key 初始化为 active context 中与 item active property 关联的 术语 定义中的索引映射的值, 或者如果不存在这样的值,则为 @index。
        4. 如果 container 包含 @language,且 expanded item 包含 @value 条目,则将 compacted item 设置为与其 @value 条目关联的值。 将 map key 设置为 expanded item 中 @language 的值(如有)。
        5. 否则,如果 container 包含 @index 且 index key 为 @index, 则将 map key 设置为 expanded item 中 @index 的值(如有)。
        6. 否则,如果 container 包含 @index 且 index key 不是 @index:
          1. 通过对 index key 进行IRI 压缩 重新初始化 container key。
          2. 将 map key 设置为 compacted item 中 container key 的第一个值(如有)。
          3. 如果 compacted item 中 container key 还有剩余值, 则使用添加值将 这些剩余值添加到 compacted item 中的 container key。 否则,从 compacted item 中移除该 条目。
        7. 否则,如果 container 包含 @id,则将 map key 设置为 compacted item 中 container key 的值,并从 compacted item 中移除 container key。
        8. 否则,如果 container 包含 @type:
          1. 将 map key 设置为 compacted item 中 container key 的第一个值(如有)。
          2. 如果 compacted item 中 container key 还有剩余值, 则使用添加值将 这些剩余值添加到 compacted item 中的 container key。
          3. 否则,从 compacted item 中移除该 条目。
          4. 如果 compacted item 包含单个 条目, 且其键展开为 @id,则将 compacted item 设置为使用 此算法递归处理的结果,传入 active context、 item active property 作为 active property, 以及由 expanded item 中 @id 的单个 条目 组成的映射 作为 element。
        9. 如果 map key 是 null, 则将其设置为对 @none 进行 IRI 压缩的结果。
        10. 使用添加值将 compacted item 添加到 map object 中的 map key 条目, 使用 as array。
      10. 否则,使用添加值将 compacted item 添加到 nest result 中的 item active property 条目, 使用 as array。
  13. 返回 result。

6.2 IRI 压缩

此算法将IRI压缩为术语或 紧凑 IRI,或将关键字压缩为 关键字别名。可传入与该 IRI关联的值,以帮助选择最 适合上下文的术语。

6.2.1 概述

本节是非规范性的。

如果传入的IRI是 null, 我们直接返回 null。 否则,如果该IRI或关键字 相对于 活动上下文的词汇表 映射, 我们首先尝试找到一个它可被压缩成的术语。 为了选择最合适的术语, 我们可能必须收集关于传入 value 的信息。 这些信息包括确定用于表达 value 的首选 容器映射、 类型映射或语言映射。 对于JSON-LD 列表,会基于 对列表中所有项都适用的最具体值来选择 类型映射 或语言映射。 收集完这些信息后, 会将其传给术语选择算法, 该算法将返回最合适的术语。

如果没有找到可用于压缩该IRI的 术语, 则尝试使用活动上下文的 词汇表 映射 压缩该IRI, 如果存在这样的映射。 如果该IRI无法被压缩, 则尝试找到一个紧凑 IRI。 只有当术语定义包含值为 true 的前缀标志 时,才会使用术语创建紧凑 IRI。 如果没有合适的紧凑 IRI, 且 compactToRelative 选项为 true, 则使用文档的基准 IRI 将该IRI转换为相对 IRI 引用。 最后,如果该IRI或关键字仍无法被压缩, 则原样返回它。

在考虑语言映射时, 也会考虑方向映射, 无论是否带有 语言映射, 并且语言 映射会被规范化为小写。

在此算法会原样返回输入IRI的情况下, 如果该IRI在 活动上下文中 可能被误认为是紧凑 IRI, 则此算法将抛出错误, 因为它没有办法返回原始IRI的无歧义表示。

6.2.2 算法

此算法接受两个必需输入和三个可选输入。 必需输入是 active context 和要压缩的 var。 可选输入是与 var 关联的 value、 vocab 标志,该标志指定传入的 var 是否应使用活动上下文的 词汇表 映射进行压缩, 以及 reverse 标志,该标志指定是否正在压缩 反向属性。 如果未传入,value 设置为 null, 且 vocab 和 reverse 都设置为 false。

  1. 如果 var 是 null,返回 null。
  2. 如果 active context 具有 null 逆上下文, 则将 active context 中的逆上下文 设置为使用 active context 调用 逆上下文创建算法 的结果。
  3. 将 inverse context 初始化为 active context 中逆上下文的值。
  4. 如果 vocab 是 true,并且 var 是 inverse context 的条目:
    1. 基于活动上下文的 默认语言 (规范化为小写)和默认基准 方向, 初始化 default language:
      1. 如果活动 上下文的默认基准 方向 不是 null,则设置为 活动 上下文的默认 语言 和默认基准 方向以下划线("_") 分隔并连接后的结果, 并规范化为小写。
      2. 否则,如果活动 上下文具有默认 语言, 则设置为该默认语言并 规范化为小写, 否则设置为 @none。
    2. 如果 value 是包含 @preserve 条目的映射, 则使用 @preserve 值中的第一个元素作为 value。
    3. 将 containers 初始化为空数组。该 数组将用于 跟踪某个术语的首选 容器映射的有序列表, 基于与 value 兼容的内容。
      注
      算法步骤可能会向 containers 追加相同的值, 但它们被添加的顺序对于选择最 合适的术语很重要。
    4. 将 type/language 初始化为 @language, 并将 type/language value 初始化为 @null。这两个 变量将用于跟踪某个术语的首选 类型映射或 语言 映射, 基于与 value 兼容的内容。
    5. 如果 value 是包含 @index 条目的 映射, 且 value 不是图对象, 则向 containers 追加值 @index 和 @index@set。
    6. 如果 reverse 是 true,将 type/language 设置为 @type,将 type/language value 设置为 @reverse,并将 @set 追加到 containers。
    7. 否则,如果 value 是列表对象,则将 type/language 和 type/language value 设置为对列表中所有项都适用的最具体值,如下:
      1. 如果 @index 不是 value 中的 条目, 则将 @list 追加到 containers。
      2. 将 list 初始化为 value 中 @list 条目关联的 数组。
      3. 将 common type 和 common language 初始化为 null。如果 list 为空,则将 common language 设置为 default language。
      4. 对于 list 中的每个 item:
        1. 将 item language 初始化为 @none,并将 item type 初始化为 @none。
        2. 如果 item 包含 @value 条目:
          1. 如果 item 包含 @direction 条目, 则将 item language 设置为 item 的 @language 条目(如有)与 item 的 @direction 以下划线("_")分隔并连接后的结果, 并规范化为小写。
          2. 否则,如果 item 包含 @language 条目, 则将 item language 设置为其关联值, 并规范化为小写。
          3. 否则,如果 item 包含 @type 条目, 则将 item type 设置为其 关联值。
          4. 否则,将 item language 设置为 @null。
        3. 否则,将 item type 设置为 @id。
        4. 如果 common language 是 null, 将 common language 设置为 item language。
        5. 否则,如果 item language 不等于 common language,并且 item 包含 @value 条目,则将 common language 设置为 @none,因为列表项具有冲突的 语言。
        6. 如果 common type 是 null, 将 common type 设置为 item type。
        7. 否则,如果 item type 不等于 common type,则将 common type 设置为 @none,因为列表项具有冲突的 类型。
        8. 如果 common language 是 @none,且 common type 是 @none,则 停止处理列表中的项,因为已经 检测到这些项之间不存在共同的语言或类型。
      5. 如果 common language 是 null, 将 common language 设置为 @none。
      6. 如果 common type 是 null, 将 common type 设置为 @none。
      7. 如果 common type 不是 @none,则将 type/language 设置为 @type,并将 type/language value 设置为 common type。
      8. 否则,将 type/language value 设置为 common language。
    8. 否则,如果 value 是图对象, 则首选最适合该特定值的映射。
      1. 如果 value 包含 @index 条目, 则将值 @graph@index 和 @graph@index@set 追加到 containers。
      2. 如果 value 包含 @id 条目, 则将值 @graph@id 和 @graph@id@set 追加到 containers。
      3. 将值 @graph、@graph@set 和 @set 追加到 containers。
      4. 如果 value 不包含 @index 条目, 则将值 @graph@index 和 @graph@index@set 追加到 containers。
      5. 如果 value 不包含 @id 条目, 则将值 @graph@id 和 @graph@id@set 追加到 containers。
      6. 将值 @index 和 @index@set 追加到 containers。
      7. 将 type/language 设置为 @type, 并将 type/language value 设置为 @id。
    9. 否则:
      1. 如果 value 是值对象:
        1. 如果 value 包含 @direction 条目 且不包含 @index 条目, 则将 type/language value 设置为 value 的 @language 条目(如有) 和 value 的 @direction 条目以下划线 ("_")分隔并连接后的结果, 并规范化为小写。 将 @language 和 @language@set 追加到 containers。
        2. 否则,如果 value 包含 @language 条目 且不包含 @index 条目, 则将 type/language value 设置为 @language 的值并规范化为小写, 并将 @language 和 @language@set追加到 containers。
        3. 否则,如果 value 包含 @type 条目,则将 type/language value 设置为 其关联值,并将 type/language 设置为 @type。
      2. 否则,将 type/language 设置为 @type, 并将 type/language value 设置为 @id, 并将 @id、@id@set、 @type 和 @set@type 追加到 containers。
      3. 将 @set 追加到 containers。
    10. 将 @none 追加到 containers。这表示 不存在容器映射,并且它将 是最后一个要检查的容器映射值,因为它 最通用。
    11. 如果处理模式 不是 json-ld-1.0,并且 value 不是映射 或不包含 @index 条目, 则将 @index 和 @index@set 追加到 containers。
    12. 如果处理模式 不是 json-ld-1.0,并且 value 是只包含 @value 条目的映射, 则将 @language 和 @language@set 追加到 containers。
    13. 如果 type/language value 是 null, 将 type/language value 设置为 @null。 这是在 inverse context entry 中存储 null 值所用的键。
    14. 将 preferred values 初始化为空数组。 此数组 将按顺序指示某个 术语的 类型映射 或 语言 映射的首选值。
    15. 如果 type/language value 是 @reverse,将 @reverse 追加到 preferred values。
    16. 如果 type/language value 是 @id 或 @reverse,并且 value 是包含 @id 条目的 映射:
      1. 如果 对 value 中 @id 条目的值进行 IRI 压缩的结果 在 active context 中具有术语 定义, 且该定义具有一个等于 value 中 @id 条目的值的 IRI 映射, 则按此顺序将 @vocab、@id 和 @none 追加到 preferred values。
      2. 否则,按此顺序将 @id、@vocab 和 @none 追加到 preferred values。
    17. 否则,按此顺序将 type/language value 和 @none 追加到 preferred values。 如果 value 是列表对象, 且 @list 的值是空 array, 则将 type/language 设置为 @any。
    18. 将 @any 追加到 preferred values。
    19. 如果 preferred values 包含任何带下划线("_")的条目, 则将该条目中从下划线到字符串末尾的子字符串 追加到 preferred values。
    20. 将 term 初始化为 术语选择算法的结果,传入 var、containers、 type/language 和 preferred values。
    21. 如果 term 不是 null,返回 term。
  5. 此时,没有简单术语可供 var 压缩为。如果 vocab 是 true,且 active context 具有词汇表映射:
    1. 如果 var 以 词汇表 映射的值开头 但更长,则将 suffix 初始化为 var 中不匹配的子字符串。如果 suffix 在 active context 中没有术语定义, 则返回 suffix。
  6. 无法使用活动上下文的 词汇表映射 压缩 var。 尝试创建一个紧凑 IRI,首先将 compact IRI 初始化为 null。此变量将用于 存储创建的紧凑 IRI(如有)。
  7. 对于 active context 中的每个 术语定义 definition:
    1. 如果 definition 的IRI 映射为 null, 其IRI 映射等于 var, 其IRI 映射不是 var 开头的子字符串, 或者 definition 没有值为 true 的前缀标志, 则 definition 的键不能用作前缀。 继续处理下一个 definition。
    2. 通过连接 definition 的键、 冒号(:)和 var 中位于 definition 的 IRI 映射值之后的子字符串, 初始化 candidate。
    3. 如果 compact IRI 是 null,或者 candidate 更短,或长度相同但字典序小于 compact IRI, 且 candidate 在 active context 中没有 术语 定义;或者如果该 术语 定义具有等于 var 的 IRI 映射 且 value 为 null, 则将 compact IRI 设置为 candidate。
  8. 如果 compact IRI 不是 null,返回 compact IRI。
  9. 为确保 IRI var 不会与紧凑 IRI混淆, 如果 var 的IRI 方案 与活动上下文中任何 前缀标志设置为 true 的术语匹配, 且 var 没有IRI authority(前面带有 双斜杠(//), 则检测到 IRI confused with prefix 错误, 并中止处理。
  10. 如果 vocab 是 false, 则使用active context 中的基准 IRI(如果存在) 将 var 转换为相对 IRI 引用。
  11. 最后,原样返回 var。

6.3 值压缩

展开会在 JSON-LD 中将所有值转换为 展开形式。 此算法执行相反的操作,将 一个值转换为压缩形式。此算法根据给定 活动上下文 中与该值关联的 活动属性相关联的 术语定义 压缩值。

6.3.1 概述

本节是非规范性的。

要压缩的 value 具有 @id 或 @value 条目。

对于前一种情况,如果 活动属性的 类型 映射设置为 @id 或 @vocab, 且 value 只由 @id 条目组成,并且如果 活动属性的 容器映射 包含 @index,则还包含一个 @index 条目,那么 value 可以通过返回使用 IRI 压缩算法 对与 @id 条目关联的值进行压缩所得的结果, 被压缩为字符串。 否则,value 不能被压缩,并按原样返回。

对于后一种情况,可能可以将 value 仅压缩为与 @value 条目关联的值。 如果活动属性具有匹配的 类型映射或语言映射,并且 要么没有 @index 条目,要么 活动属性的 容器映射包含 @index,则可以这样做。也可以在 @value 是 value 中唯一的条目时这样做 (如果活动属性的 容器映射 包含 @index,则可另有一个 @index 条目),并且 其关联值不是字符串、不存在 默认 语言,或者存在针对 活动属性的显式 null 语言 映射。

6.3.2 算法

此算法有三个必需输入:active context、 active property 和要压缩的 value。

  1. 将 result 初始化为 value 的副本。
  2. 如果 active context 具有 null 逆上下文, 则将 active context 中的逆上下文 设置为使用 active context 调用 逆上下文创建算法 的结果。
  3. 将 inverse context 初始化为 active context 中逆上下文的值。
  4. 将 language 初始化为 active context 中 active property 的语言映射(如有),否则初始化为 active context 的默认语言。
  5. 将 direction 初始化为 active context 中 active property 的方向映射(如有),否则初始化为 active context 的默认基准方向。
  6. 如果 value 具有 @id 条目 且除了 @index 之外没有其他 条目:
    1. 如果 active property 的类型 映射 设置为 @id,则将 result 设置为 使用 false 作为 vocab 对 @id 条目关联的值进行 IRI 压缩 的结果。
    2. 否则,如果 active property 的类型映射 设置为 @vocab,则将 result 设置为 对 @id 条目关联的值进行 IRI 压缩 的结果。
  7. 否则,如果 value 具有 @type 条目,其 值与 active property 的类型 映射匹配, 则将 result 设置为 value 的 @value 条目 关联的值。
  8. 否则,如果 active property 的类型映射是 @none, 或者 value 具有 @type 条目, 且 value 中 @type 的值与 active property 的类型映射不匹配, 则让 value 保持原样,因为值压缩已禁用。
    1. 将 result 中 @type 的任何值替换为 对 @type 条目的值进行 IRI 压缩 的结果。
  9. 否则,如果 @value 条目的值不是 字符串:
    1. 如果 value 具有 @index 条目, 并且与 active property 关联的 容器映射包含 @index, 或者如果 value 没有 @index 条目, 则将 result 设置为与 @value 条目关联的值。
  10. 否则,如果 value 具有 @language 条目, 其值与 language 精确匹配; 如果它不是 null,则使用不区分大小写的比较; 或者如果 language 是 null,则不存在该条目, 并且 value 具有 @direction 条目, 其值与 direction 精确匹配; 如果它不是 null,则如此;或者如果 direction 是 null,则不存在该条目:
    1. 如果 value 具有 @index 条目, 且与 active property 关联的 容器映射包含 @index, 或者 value 没有 @index 条目, 则将 result 设置为与 @value 条目关联的值。
  11. 如果 result 是 map, 则将 result 中的每个键替换为 对该键进行IRI 压缩的结果。
  12. 返回 result。

7. 扁平化算法

以下章节描述用于扁平化 JSON-LD 文档、 创建节点映射以及生成空白节点的算法。

7.1 扁平化算法

此算法通过将一个节点的所有 属性收集到单个映射 中,并使用 空白 节点标识符标记所有空白节点, 来扁平化展开后的 JSON-LD 文档。 由此得到的文档统一形状,可能会显著简化 某些应用中处理 JSON-LD 数据所需的代码。

7.1.1 概述

本节是非规范性的。

首先,使用 节点映射生成算法 生成一个 node map, 该算法将一个节点的所有 属性收集到单个 映射中。 在下一步,node map 会被 转换为处于 扁平化文档形式的 JSON-LD 文档。

7.1.2 算法

该算法接受一个必需和一个可选输入变量。 必需输入是要扁平化的 element。 可选输入是 ordered 标志,用于在注明之处按字典序排列 映射条目键。 如果未传入,ordered 标志设置为 false。

此算法使用 生成空白节点标识符算法 来生成新的空白节点 标识符 并重新标记现有空白节点 标识符。 生成空白节点标识符算法 维护一个 identifier map 以确保源文档中的空白节点标识符 被一致地重新映射为新的空白节点标识符, 从而避免冲突。 因此,在运行此算法之前,会重置 identifier map。

  1. 将 node map 初始化为一个映射,它由 单个条目组成,其 键为 @default,其值为 空映射。
  2. 执行节点映射生成算法,传入 element 和 node map。
  3. 将 default graph 初始化为 node map 的 @default 条目的值,该值是表示 默认图的 映射。
  4. 对于 node map 中的每个键值对 graph name-graph,其中 graph name 不是 @default, 如果 ordered 为 true, 则按 graph name 字典序排列, 执行以下步骤:
    1. 如果 default graph 没有 graph name 条目, 创建 一个,并将其值初始化为一个映射,该映射由一个 @id 条目组成,其值设置为 graph name。
    2. 使用变量 entry 引用 default graph 中与 graph name 条目关联的值。
    3. 向 entry 添加一个 @graph 条目,并将其设置为 空数组。
    4. 对于 graph 中的每个 id-node 对,按 id 字典序排列 (如果 ordered 为 true), 将 node 添加到 entry 的 @graph 条目中, 除非 node 唯一的 条目是 @id。
  5. 初始化一个空数组 flattened。
  6. 对于 default graph 中的每个 id-node 对,按 id 字典序排列 (如果 ordered 为 true), 将 node 添加到 flattened, 除非 node 唯一的条目是 @id。
  7. 返回 flattened。

7.2 节点映射生成

此算法创建一个映射 node map,其中保存 传入的展开文档中表示的图和节点 的索引表示。所有未由 IRI 唯一标识的 节点都会被分配一个 (新的)空白节点标识符。 生成的 node map 将为文档中的每个图拥有一个 映射条目,其值是另一个对象,该对象为文档中表示的每个 节点拥有一个 条目。 默认图存储在 @default 条目下,所有其他图 存储在其图名下。

7.2.1 概述

本节是非规范性的。

该算法递归遍历一个展开的 JSON-LD 文档,以将一个 节点的所有 条目 收集到单个映射中。该算法更新一个 映射 node map,其键表示文档中使用的 图名 (默认 图存储在 @default 条目下), 其关联值是映射, 这些映射对 图中的 节点建立索引。如果某个 条目的 值是节点 对象, 它会被替换为只包含一个 @id 条目的 节点对象。 如果一个节点对象 没有 @id 条目,或者它 由空白节点 标识符标识, 则会生成一个新的 空白节点标识符。 这种对空白节点 标识符的重新标记 也会用于属性和 @type 的值。

7.2.2 算法

该算法以展开的 JSON-LD 文档 element 和对 一个映射 node map 的引用作为输入。此外它还有可选参数 active graph(默认为 @default)、active subject、 active property,以及对映射 list 的引用。如果 未传入,active subject、active property 和 list 会被设置为 null。

  1. 如果 element 是数组,则按如下方式处理 element 中的每个 item,然后返回:
    1. 递归运行此算法,传入 item 作为 element, node map、active graph、active subject、 active property 和 list。
  2. 否则 element 是映射。使用变量 graph 引用 node map 的活动图 条目的值所对应的 映射。如果 active subject 是 null,则将 node 设置为 null, 否则使用变量 subject node 引用 graph 的 active subject 条目。
  3. 对于 element 的 @type 条目中的每个 item(如果有),或者如果 @type 的值存在且 不是数组,则对于 @type 的值:
    1. 如果 item 是空白节点 标识符,则将其替换为一个新 生成的空白节点标识符, 传入 item 作为 identifier。
  4. 如果 element 具有 @value 条目,执行以下步骤:
    1. 如果 list 是 null:
      1. 如果 subject node 没有 active property 条目, 创建一个,并将其值初始化为包含 element 的 数组。
      2. 否则,将 element 与 subject node 的 active property 条目关联的 数组 中的每一项进行比较。如果没有与 element 等价的项, 则将 element 追加到该 数组。如果两个 映射具有等价的 映射条目,则认为它们相等。
    2. 否则,将 element 追加到 list 的 @list 条目中。
  5. 否则,如果 element 具有 @list 条目,执行 以下步骤:
    1. 初始化一个新的映射 result, 它由单个条目 @list 组成,其值初始化为空 数组。
    2. 递归调用此算法,传入 element 的 @list 条目的值作为 element、 node map、active graph、 active subject、active property,以及 result 作为 list。
    3. 如果 list 是 null, 则将 result 追加到 subject node 的 active property 条目的值。
    4. 否则,将 result 追加到 list 的 @list 条目中。
  6. 否则 element 是节点对象,执行 以下步骤:
    1. 如果 element 具有 @id 条目,则将 id 设置为其值,并从 element 中移除该 条目。 如果 id 是空白节点 标识符,则将其替换为一个新 生成的空白节点标识符, 传入 id 作为 identifier。
    2. 否则,将 id 设置为 生成空白节点标识符算法的结果, 传入 null 作为 identifier。
    3. 如果 graph 不包含 id 的 条目,则创建一个, 并将其值初始化为一个映射,该映射由单个 条目 @id 组成,其 值为 id。
    4. 使用变量 node 引用 graph 的 id 条目的值。
    5. 如果 active subject 是映射,则正在处理反向属性 关系。执行以下步骤:
      1. 如果 node 没有 active property 条目, 创建一个,并将其值初始化为包含 active subject 的 数组。
      2. 否则,将 active subject 与 node 的 active property 条目关联的 数组 中的每一项进行比较。如果没有与 active subject 等价的项, 则将 active subject 追加到该 数组。如果两个 映射具有等价的 映射条目,则认为它们相等。
    6. 否则,如果 active property 不是 null,执行以下 步骤:
      1. 创建一个新的映射 reference,它由单个 条目 @id 组成,其值为 id。
      2. 如果 list 是 null:
        1. 如果 subject node 没有 active property 条目, 创建一个,并将其值初始化为包含 reference 的 数组。
        2. 否则,将 reference 与 subject node 的 active property 条目关联的 数组中的 每一项进行比较。如果没有与 reference 等价的项, 则将 reference 追加到该 数组。如果两个 映射具有等价的 映射条目,则认为 它们相等。
      3. 否则,将 reference 追加到 list 的 @list 条目中。
    7. 如果 element 具有 @type 条目,则将 其关联数组中的每一项追加到 node 的 @type 条目关联的 数组中, 除非它已经在该 数组中。最后 从 element 中移除 @type 条目。
    8. 如果 element 具有 @index 条目,则将 node 的 @index 条目 设置为其值。如果node 已经具有值不同的 @index 条目,则检测到 conflicting indexes 错误并中止处理。否则,继续从 element 中移除 @index 条目。
    9. 如果 element 具有 @reverse 条目:
      1. 创建一个映射 referenced node,其中包含单个 条目 @id,其 值为 id。
      2. 将 reverse map 初始化为 element 的 @reverse 条目的值。
      3. 对于 reverse map 中的每个键值对 property-values:
        1. 对于 values 中的每个 value:
          1. 递归调用此算法,传入 value 作为 element、node map、active graph、 referenced node 作为 active subject,以及 property 作为 active property。传入一个 映射 作为 active subject 表示 算法正在处理反向属性关系。
      4. 从 element 中移除 @reverse 条目。
    10. 如果 element 具有 @graph 条目,则递归调用此 算法,传入 @graph 条目的值作为 element、 node map,以及 id 作为 active graph,然后移除 element 中的 @graph 条目。
    11. 如果 element 具有 @included 条目, 则递归调用此算法,传入 @included 条目的值作为 element、 node map 和 active graph, 然后从 element 中移除 @included 条目。
    12. 最后,对于 element 中按 property 排序的每个键值对 property-value, 执行以下步骤:
      1. 如果 property 是空白 节点标识符,则将其替换为一个新 生成的空白节点标识符, 传入 property 作为 identifier。
        注
        使用空白 节点标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除。
      2. 如果 node 没有 property 条目,创建一个并 将其值初始化为空 数组。
      3. 递归调用此算法,传入 value 作为 element、 node map、active graph、id 作为 active subject, 以及 property 作为 active property。

7.3 合并节点映射

此算法使用由节点映射生成算法 创建的 graph map 中包含的所有图,创建一个新的映射, 该映射将主语映射到 节点, 以创建合并后的节点 对象,其中包含 node map 中每个图内为给定 主语定义的信息。

  1. 创建 result 作为空映射
  2. 对于 graph map 中的每个 graph name 和 node map, 以及 node map 中的每个 id 和 node:
    1. 将 merged node 初始化为 result 中 id 的值; 如果它不存在,则 用一个新的映射 初始化,该映射由单个 条目 @id 组成,其值 为 id。
    2. 对于 node 中的每个 property 和 values:
      1. 如果 property 是 除 @type 之外的 关键字,则将 property 和值添加到 merged node。
      2. 否则,将 values 中的每个元素合并到 merged node 中 property 对应的值中,并在必要时将其初始化为空 数组。
  3. 返回 result。

7.4 生成空白节点标识符

此算法用于生成新的 空白 节点标识符,或者用于 重新标记现有空白节点标识符, 以避免因引入新标识符而发生冲突。

7.4.1 概述

本节是非规范性的。

最简单的情况是,identifier map 中已经存在传入 identifier 对应的 空白节点标识符, 此时直接返回它。否则,会生成一个新的 空白节点标识符。 如果传入的 identifier 不是 null, 则会在 identifier map 中创建一个条目,将 identifier 与该 空白节点 标识符关联起来。

7.4.2 算法

该算法接受单个输入变量 identifier,它可以 是 null。该算法 维护一个 identifier map,用于将现有 空白 节点标识符重新标记为新的 空白节点 标识符, 该映射会在调用算法初始化时重置。

  1. 如果 identifier 不是 null,且在 identifier map 中有条目,则返回映射后的标识符。
  2. 否则,生成一个新的唯一空白节点 标识符。
  3. 如果 identifier 不是 null,则在 identifier map 中为 identifier 创建一个新条目,并将其值 设置为新的空白节点 标识符。
  4. 返回新的空白节点 标识符。
注

生成新的空白节点 标识符的一种方式是维护一个计数器, 在生成新标识符时递增它,并将其追加到 诸如 _:b 的字符串后。

8. RDF 序列化/反序列化算法

本节描述将 JSON-LD 文档反序列化为 RDF 数据集以及 反向操作的算法。这些算法为内存中实现而设计, 可随机访问映射元素。

8.1 将 JSON-LD 反序列化为 RDF 算法

此算法将 JSON-LD 文档反序列化为RDF 数据集。 请注意,RDF 不允许将空白节点用作 属性, 而 JSON-LD 允许。因此,默认情况下, 在将 JSON-LD 解释为 RDF 时,会丢弃那些本来会包含空白节点作为 属性的 三元组。

注

使用空白节点 标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除。

如果 rdfDirection 选项不是 null, 则会使用特殊处理,从 i18n-datatype 或 compound-literal 形式进行转换。

实现 MUST 只生成格式良好的 三元组和图名:

8.1.1 概述

本节是非规范性的。

JSON-LD 文档会被展开,并使用 节点映射生成算法转换为 node map。 这允许提取并扁平化文档中表示的每个图, 从而更容易处理每个 节点对象。 来自 node map 的每个图都会被处理以提取三元组, 任何(非默认)图名都会应用到这些三元组上,以创建 RDF 数据集。 node map 中的每个 节点对象 都有一个 @id 条目, 它对应于主语, 其他条目 表示谓词。 每个条目值 要么是 IRI、空白节点标识符, 要么可以被转换为RDF 字面量, 以生成三元组。 列表会使用 列表到 RDF 转换算法转换为 RDF 集合。

8.1.2 算法

该算法接受一个映射 node map,它是 节点映射生成算法的结果,以及一个 RDF 数据集 dataset,新的图和三元组 会被添加到其中。 它还接受两个可选输入变量:produceGeneralizedRdf 和 rdfDirection。 除非 produceGeneralizedRdf 选项 被设置为 true,否则包含空白节点 谓词的 三元组 会从输出中排除。

注

使用空白节点 标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除, 对广义 RDF 数据集的支持也是如此, 因而 produceGeneralizedRdf 选项也可能 被移除。

  1. 对于 node map 中按 graph name 排序的每个 graph name 和 graph:
    1. 如果 graph name 不是格式良好的,则继续处理 下一个 graph name-graph 对。
    2. 如果 graph name 是 @default, 则将 triples 初始化为 dataset 的 defaultGraph 属性值。 否则,将 triples 初始化为空 RdfGraph, 并使用 dataset 的 add 方法将其添加到 dataset,同时传入 graph name 作为 graphName。
    3. 对于 graph 中按 subject 排序的每个 subject 和 node:
      1. 如果 subject 不是格式良好的,则继续处理 下一个 subject-node 对。
      2. 对于 node 中按 property 排序的每个 property 和 values:
        1. 如果 property 是 @type,则对于 values 中的每个 type, 创建一个新的 RdfTriple, 由 subject、作为 predicate 的 rdf:type, 以及作为 object 的 type 组成, 并使用 triples 的 add 方法 将其添加到 triples, 除非 type 不是格式良好的。
        2. 否则,如果 property 是 关键字, 则继续处理下一个 property-values 对。
        3. 否则,如果 property 是空白 节点标识符,并且 produceGeneralizedRdf 选项不是 true, 则继续处理下一个 property-values 对。
          注
          使用空白 节点标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除, 对广义 RDF 数据集的支持也是如此, 因而 produceGeneralizedRdf 选项也可能被移除。
        4. 否则,如果 property 不是格式良好的, 则继续处理下一个 property-values 对。
        5. 否则,property 是 IRI或 空白 节点标识符。对于 values 中的每个 item:
          1. 将 list triples 初始化为空 数组。
            注
            item 是 值 对象、列表 对象, 或节点 对象。
          2. 向 triples 添加一个 三元组, 由 subject、property,以及 使用 对象到 RDF 转换算法 (传入 item 和 list triples) 的结果组成,使用 triples 的 add 方法添加, 除非结果为 null, 表示必须忽略一个非格式良好的 资源。
          3. 使用 triples 的 add 方法,将 list triples 中的所有 RdfTriple 实例 添加到 triples。

8.2 对象到 RDF 转换

此算法接受一个节点对象、列表对象或 值对象, 并将其转换为一个资源,以用作 三元组的 宾语。 如果传给该算法的是一个包含相对 IRI 引用的 节点对象, 则返回 null,随后会导致所得 三元组被忽略。 如果输入是列表对象,它还会 返回从该输入创建的三元组。

8.2.1 概述

本节是非规范性的。

值对象 会按照 § 8.6 数据 往返转换 中所述转换为 RDF 字面量, 而节点 对象会转换为 IRI、 空白 节点标识符 或 null。

8.2.2 算法

该算法接受两个参数:item,它 MUST 是 值 对象、列表 对象或节点对象; 以及 list triples,它是一个空数组。

  1. 如果 item 是节点对象,且其 @id 条目的值 不是格式良好的,则返回 null。
  2. 如果 item 是节点对象,则返回与其 @id 条目关联的 IRI或 空白节点 标识符。
  3. 如果 item 是列表对象, 则返回 列表转换算法的结果,传入 item 中与 @list 条目关联的值,以及 list triples。
  4. 否则,item 是值对象。将 value 初始化为 item 中与 @value 条目关联的值。
  5. 将 datatype 初始化为 item 的 @type 条目关联的值;如果 item 没有这样的条目,则初始化为 null。
  6. 如果 datatype 不是 null, 且既不是格式良好的 IRI, 也不是 @json,则返回 null。
  7. 如果 item 具有 @language 条目,且该条目不是 格式良好的,则返回 null。
  8. 如果 datatype 是 @json, 则使用将 value 的 内部表示转换为 JSON 的结果,将 value 转换为规范词法形式, 并将 datatype 设置为 rdf:JSON。
    问题
    JSON 规范化方案(JCS)[RFC8785] 是一个用于 JSON 规范化的新兴标准。 本规范很可能会更新,以要求这样的规范表示。 提醒用户不要依赖 JSON 字面量作为 RDF 字面量的词法表示, 因为序列化细节可能会在本文档的未来修订版中改变。
  9. 如果 value 是 true 或 false,则将 value 设置为 字符串 true 或 false,这就是 规范词法 形式,如 § 8.6 数据往返转换 中所述。如果 datatype 是 null, 则将 datatype 设置为 xsd:boolean。
  10. 否则,如果 value 是具有非零小数 部分(模 1 运算的结果)的 数字 或绝对值大于或等于 1021, 或者 value 是数字 且 datatype 等于 xsd:double,则将 value 转换为 字符串, 其形式为 [XMLSCHEMA11-2] 中定义并在 § 8.6 数据往返转换中描述的 xsd:double 的 规范 词法形式。 如果 datatype 是 null, 则将 datatype 设置为 xsd:double。
  11. 否则,如果 value 是 数字, 则将它转换为 字符串,其形式为 [XMLSCHEMA11-2] 中定义并在 § 8.6 数据往返转换中描述的 xsd:integer 的 规范 词法形式。 如果 datatype 是 null, 则将 datatype 设置为 xsd:integer。
    注
    由上一步可知,value 没有非零小数部分。
  12. 否则,如果 datatype 是 null, 则根据 item 是否具有 @language 条目, 将 datatype 设置为 xsd:string 或 rdf:langString。
  13. 如果 item 包含 @direction 条目, 且 rdfDirection 不是 null, 则 item 是一个使用特殊规则序列化的 值对象。
    1. 将 language 初始化为 item 中 @language 的值并规范化为小写, 如果没有这样的条目,则初始化为空字符串("")。
      注
      通常语言标签不会被规范化, 但在创建 i18n-datatype 或 compound-literal 值时,值会被规范化为小写,以提高互操作性。
    2. 如果 rdfDirection 是 i18n-datatype, 则将 datatype 设置为把 language 和 item 中 @direction 的值以下划线 ("_")分隔并追加到 https://www.w3.org/ns/i18n# 后的结果。 使用 value 和 datatype 将 literal 初始化为 RDF 字面量。
      注
      处理器 MAY 将 语言 标签规范化为小写。
      注
      由于 @direction 可以在没有 @language 的情况下使用, 因此可以合法地创建一个数据类型 IRI, 例如 http://w3.org/ns/i18n#_ltr,它并不编码 语言标签。
    3. 否则,如果 rdfDirection 是 compound-literal:
      1. 将 literal 初始化为新的 空白节点。
      2. 使用 literal 作为主语、 rdf:value 作为谓词,以及 item 中 @value 的值作为宾语, 创建一个新的三元组,并将其添加到 list triples。
      3. 如果 item 有 @language 条目, 使用 literal 作为主语、 rdf:language 作为谓词,以及 language 作为宾语,创建一个新的三元组,并将其添加到 list triples。
      4. 使用 literal 作为主语、 rdf:direction 作为谓词,以及 item 中 @direction 的值 作为宾语,创建一个新的三元组,并将其添加到 list triples。
  14. 否则,使用 value 和 datatype 将 literal 初始化为 RDF 字面量。如果 item 具有 @language 条目, 则将与 @language 条目关联的值添加为 literal 的语言标签。
  15. 返回 literal。

8.3 列表到 RDF 转换

列表转换是取得一个列表对象 并将其转换为 [RDF11-MT] 中 RDF 语义所定义的 RDF 集合 的过程。

8.3.1 概述

本节是非规范性的。

对于列表中的每个元素, 都会分配一个新的 空白节点标识符, 用于生成 rdf:first 和 rdf:rest。该 算法返回列表头,它要么是第一个分配的 空白 节点标识符,要么在 列表为空时为 rdf:nil。如果某个列表元素表示 IRI, 则省略对应的 rdf:first 三元组。

8.3.2 算法

该算法接受两个输入:一个数组 list 和一个空数组 list triples,后者用于返回 生成的三元组。

  1. 如果 list 为空,返回 rdf:nil。
  2. 否则,创建一个数组 bnodes,由 list 中每个条目的一个 新生成的空白节点标识符 组成。
  3. 对于来自 bnodes 的 subject 和来自 list 的 item 的每一对:
    1. 将 embedded triples 初始化为新的空数组。
    2. 将 object 初始化为使用 对象到 RDF 转换算法的结果, 传入 item 以及 embedded triples 作为 list triples。
    3. 除非 object 为 null,否则将一个由 subject、rdf:first 和 object 组成的 三元组 追加到 list triples。
    4. 将 rest 初始化为 bnodes 中的下一个条目,若不存在则为 rdf:nil。将一个由 subject、 rdf:rest 和 rest 组成的 三元组 追加到 list triples。
    5. 将 embedded triples 中的所有值追加到 list triples
  4. 返回 bnodes 中的第一个 空白节点,或者如果 bnodes 为空,则返回 rdf:nil。

8.4 将 RDF 序列化为 JSON-LD 算法

此算法将由一个默认图 和零个或多个 命名图 组成的RDF 数据集 序列化为 JSON-LD 文档。

在 RDF 抽象语法中,RDF 字面量具有 词法形式,如 [RDF11-CONCEPTS] 中所定义。这些 字面量的形式会在基于这些 字面量创建JSON-LD 值时使用。

8.4.1 概述

本节是非规范性的。

遍历数据集中的每个图,将每个 RDF 集合转换为列表, 并为所有 RDF 字面量、 IRI 和空白节点 标识符生成展开形式的 JSON-LD 文档。 如果 useNativeTypes 标志设置为 true, 具有等于 xsd:integer 或 xsd:double 的 数据类型 IRI 的 RDF 字面量 会被转换为 JSON 数字,而具有等于 xsd:boolean 的 数据类型 IRI 的 RDF 字面量 会根据其 词法形式 被转换为 true 或 false,如 § 8.6 数据 往返转换中所述。 除非 useRdfType 标志设置为 true,否则只要关联的宾语是 IRI或 空白节点 标识符,rdf:type 谓词就会被序列化为 @type。

如果 rdfDirection 选项不是 null, 则会使用特殊处理,从 i18n-datatype 或 compound-literal 形式进行转换。

8.4.2 算法

该算法接受一个必需输入和四个可选输入: 一个 RDF 数据集 dataset; 四个可选参数是 ordered 标志,默认为 false,用于在注明之处按字典序排列 映射条目键, rdfDirection 默认为 null, useNativeTypes 标志,默认为 false, 以及 useRdfType 标志,默认为 false。

dataset 是iterable,用于遍历 图以及 图名, 它们包含在 RdfDataset 中。每个 图也都是 iterable, 用于遍历包含在 RdfGraph 中的 三元组。

  1. 将 default graph 初始化为空映射。
  2. 将 graph map 初始化为一个映射,它由单个 条目 @default 组成,其值引用 default graph。
  3. 将 referenced once 初始化为空 映射。
  4. 将 compound literal subjects 初始化为空 映射。
  5. 对于 dataset 中的每个 graph:
    1. 如果 graph 是默认图, 则将 name 初始化为 @default,否则初始化为 与 graph 关联的 图名。
    2. 如果 graph map 没有 name 条目,则创建一个并将 其值设置为空映射。
    3. 如果 compound literal subjects 没有 name 条目,则创建一个并将 其值设置为空映射。
    4. 如果 graph 不是默认图,且 default graph 没有 name 条目, 则创建这样的条目,并将其值初始化 为一个新的 映射,该映射包含单个 条目 @id, 其值为 name。
    5. 使用变量 node map 引用 graph map 中 name 条目的值。
    6. 使用变量 compound map 引用 compound literal subjects 中 name 条目的值。
    7. 对于 graph 中的每个 三元组, 它由 subject、predicate 和 object 组成:
      1. 如果 node map 没有 subject 条目, 创建一个,并将其值初始化为新的映射, 该映射由单个条目 @id 组成,其值 设置为 subject。
      2. 使用变量 node 引用 node map 中 subject 条目的值。
      3. 如果 rdfDirection 选项 是 compound-literal 且 predicate 是 rdf:direction, 则在 compound map 中为 subject 添加一个条目,其值为 true。
      4. 如果 object 是 IRI或 空白 节点标识符, 且 node map 没有 object 条目, 则创建一个,并将其值初始化为一个新的映射, 该映射由单个条目 @id 组成,其值 设置为 object。
      5. 如果 predicate 等于 rdf:type,且 useRdfType 标志不是 true,并且 object 是 IRI或 空白 节点标识符, 则将 object 追加到 node 的 @type 条目的值中; 除非这样的项已经存在。 如果不存在这样的条目,则创建一个, 并将其初始化为只包含 object 的数组。最后,继续处理下一个 三元组。
      6. 将 value 初始化为使用 RDF 到对象转换算法的结果, 传入 object、 rdfDirection 和 useNativeTypes。
      7. 如果 node 没有 predicate 条目,则创建一个 并将其值初始化为空数组。
      8. 如果在 node 的 predicate 条目关联的 数组 中没有与 value 等价的项,则将对 value 的引用追加到该 数组。如果两个 映射 具有等价的映射条目, 则认为它们相等。
      9. 如果 object 是 rdf:nil,它表示 RDF 集合的终止:
        1. 使用变量 usages 引用 node map 的 object 条目的 usages 条目。
        2. 将一个由三个 条目 node、property 和 value 组成的新映射 追加到 usages 数组。其中 node 条目 设置为对 node 的引用,property 设置为 predicate, value 设置为对 value 的引用。
      10. 否则,如果 referenced once 有 object 的条目, 则将 referenced once 的 object 条目设置为 false。
      11. 否则,如果 object 是空白 节点标识符, 它可能表示一个列表节点:
        1. 将 referenced once 的 object 条目设置为一个新的 映射,该映射由三个 条目 node、property 和 value 组成并追加到 usages 数组。其中 node 条目 设置为对 node 的引用,property 设置为 predicate, value 设置为对 value 的引用。
  6. 对于 graph map 中的每个 name 和 graph object:
    1. 如果 compound literal subjects 有 name 的条目,则对于该条目中的每个键 cl:
      1. 将 cl entry 初始化为 referenced once 中 cl 的值, 如果 cl entry 不是映射,则继续处理下一个 cl。
      2. 将 node 初始化为 cl entry 中 node 的值。
      3. 将 property 初始化为 cl entry 中 property 的值。
      4. 将 value 初始化为 cl entry 中 value 的值。
      5. 将 cl node 初始化为 graph object 中 cl 的值,并从 graph object 中移除该条目, 如果 cl node 不是映射,则继续处理下一个 cl。
      6. 对于 node 中 property 的值里的每个 cl reference, 其中 cl reference 中 @id 的值是 cl:
        1. 删除 cl reference 中的 @id 条目。
        2. 向 cl reference 添加一个 条目 @value,其值取自 cl node 中的 rdf:value 条目。
        3. 如果有,则向 cl reference 添加一个 条目 @language,其值取自 cl node 中的 rdf:language 条目。 如果该值按照 [BCP47] 的 第 2.2.9 节不是格式良好的, 则检测到 invalid language-tagged string 错误,并中止处理。
        4. 如果有,则向 cl reference 添加一个 条目 @direction,其值取自 cl node 中的 rdf:direction 条目。 如果该值不是 "ltr" 或 "rtl",则检测到 invalid base direction 错误,并中止处理。
    2. 如果 graph object 没有 rdf:nil 条目,则继续处理 下一个 name-graph object 对,因为该图 不包含任何需要转换的列表。
    3. 将 nil 初始化为 graph object 的 rdf:nil 条目 的值。
    4. 对于 nil 的 usages 条目中的每个项 usage,执行以下步骤:
      1. 将 node 初始化为 usage 的 node 条目的值的值,将 property 初始化为 usage 的 property 条目的值, 并将 head 初始化为 usage 的 value 条目 的值。
      2. 初始化两个空数组:list 和 list nodes。
      3. 当 property 等于 rdf:rest, node 的 @id 条目 的值是空白 节点标识符, referenced once 中与 node 的 @id 条目关联的 条目的值是 映射, node 具有 rdf:first 和 rdf:rest 条目, 它们的值都是由单个元素组成的 数组, 且 node 除了一个可选的 @type 条目外没有其他 条目,而该条目的值是一个 只有一个项且等于 rdf:List 的数组时, node 表示一个格式良好的列表节点。 执行以下步骤,沿列表向其头部反向遍历:
        1. 将 node 的 rdf:first 条目中的 唯一项追加到 list 数组。
        2. 将 node 的 @id 条目的值追加到 list nodes 数组。
        3. 将 node usage 初始化为 referenced once 中与 node 的 @id 条目关联的 条目的值。
        4. 将 node 设置为 node usage 的 node 条目 的值,将 property 设置为 node usage 的 property 条目的值,并将 head 设置为 node usage 的 value 条目 的值。
        5. 如果 node 的 @id 条目是 IRI 而不是空白 节点标识符, 则退出 while 循环。
      4. 从 head 中移除 @id 条目。
      5. 反转 list 数组的顺序。
      6. 向 head 添加一个 @list 条目,并将 其值初始化为 list 数组。
      7. 对于 list nodes 中的每个项 node id,从 graph object 中移除 node id 条目。
  7. 初始化一个空数组 result。
  8. 对于 default graph 中的每个 subject 和 node,按 subject 字典序排列 (如果 ordered 是 true):
    1. 如果 graph map 具有 subject 条目:
      1. 向 node 添加一个 @graph 条目,并将 其值初始化为空数组。
      2. 对于 graph map 的 subject 条目中按 s 字典序排列的每个键值对 s-n (如果 ordered 是 true), 在移除其 usages 条目后,将 n 追加到 node 的 @graph 条目, 除非 n 剩余的唯一 条目是 @id。
    2. 在移除 node 的 usages 条目后,将 node 追加到 result,除非剩余的唯一 条目是 @id。
  9. 返回 result。

8.5 RDF 到对象转换

此算法将 RDF 字面量转换为 JSON-LD 值对象, 并将 RDF 空白 节点或 IRI 转换为 JSON-LD 节点对象。

8.5.1 概述

本节是非规范性的。

RDF 字面量 被转换为 值对象, 而 IRI 和 空白 节点标识符被 转换为节点 对象。

数据类型为 rdf:JSON 的字面量 会使用基于 [JSON-LD11] 中 JSON datatype 所定义词法到值映射的内部表示, 转换为一个值对象, 并使用 @type 为 @json。

当 rdfDirection 选项设置为 i18n-datatype 时, 数据类型以 https://www.w3.org/ns/i18n# 开头的字面量 会通过从数据类型中解码 语言 标签和基准方向, 转换为值对象。

当 rdfDirection 选项设置为 compound-literal 时, 使用 rdf:direction 的空白节点对象 会通过解码 rdf:value、rdf:language 和 rdf:direction 属性,转换为 值对象。

如果 useNativeTypes 标志设置为 true, 具有等于 xsd:integer 或 xsd:double 的 数据类型 IRI 的 RDF 字面量 会被转换为 JSON 数字,而具有等于 xsd:boolean 的 数据类型 IRI 的 RDF 字面量 会根据其 词法形式 被转换为 true 或 false,如 § 8.6 数据 往返转换中所述。

8.5.2 算法

该算法接受三个必需输入: 要转换为映射的 value, rdfDirection, 以及一个标志 useNativeTypes。

  1. 如果 value 是 IRI或 空白节点 标识符,返回一个新的映射, 该映射由单个条目 @id 组成,其值设置为 value。
  2. 否则,value 是 RDF 字面量:
    1. 初始化一个新的空映射 result。
    2. 将 converted value 初始化为 value。
    3. 将 type 初始化为 null
    4. 如果 useNativeTypes 是 true
      1. 如果 value 的 数据类型 IRI 等于 xsd:string,则将 converted value 设置为 value 的 词法 形式。
      2. 否则,如果 value 的 数据类型 IRI 等于 xsd:boolean,则如果 value 的 词法 形式 匹配 true,将 converted value 设置为 true;如果匹配 false,则设置为 false。如果都不匹配, 将 type 设置为 xsd:boolean。
      3. 否则,如果 value 的 数据类型 IRI 等于 xsd:integer 或 xsd:double,且其 词法 形式 按照 [XMLSCHEMA11-2] 是有效的 xsd:integer 或 xsd:double, 则将 converted value 设置为将 词法 形式 转换为 JSON 数字的结果。
    5. 否则,如果处理模式 不是 json-ld-1.0, 并且 value 是 JSON 字面量, 则将 converted value 设置为 把 value 的词法值 转换为 JSON-LD 内部表示的结果,并将 type 设置为 @json。 如果 value 的词法值不是符合 JSON 语法 [RFC8259] 的有效 JSON, 则检测到 invalid JSON literal 错误,并中止处理。
    6. 否则,如果 value 的 数据类型 IRI 以 https://www.w3.org/ns/i18n# 开头, 且 rdfDirection 是 i18n-datatype:
      1. 将 converted value 设置为 value 的 词法形式。
      2. 如果该 数据类型 IRI的 片段 标识符 中直到下划线("_")之前的字符串前缀不为空, 则向 result 添加一个 条目 @language,并将其值设置为该前缀。
        注
        由于 @direction 可以在没有 @language 的情况下使用, 因此可以合法地创建一个数据类型 IRI, 例如 http://w3.org/ns/i18n#_ltr,它并不编码 语言标签。
      3. 向 result 添加一个 条目 @direction,并将其值设置为 片段 标识符中下划线("_")之后的子字符串。
    7. 否则,如果 value 是 带语言标签的 字符串, 则向 result 添加一个 条目 @language,并将其值设置为 value 的 语言标签。
    8. 否则,将 type 设置为 value 的 数据类型 IRI, 除非它等于被忽略的 xsd:string。
    9. 向 result 添加一个 条目 @value,其值 设置为 converted value。
    10. 如果 type 不是 null,则向 result 添加一个条目 @type, 其值设置为 type。
    11. 返回 result。

8.6 数据往返转换

在将 JSON-LD 反序列化为 RDF时, JSON 原生数字会根据该 数字是否具有非零 小数部分 (模 1 运算的结果)自动类型强制为 xsd:integer 或 xsd:double,布尔值 true 和 false 会被强制为 xsd:boolean, 而字符串会被 强制为 xsd:string。 JSON、数值或布尔值本身会被转换为 规范词法形式,即 [XMLSCHEMA11-2] 中定义的确定性字符串表示。

整数的规范词法 形式,即没有非零 小数部分 且绝对值小于 1021 的 数字, 或被强制为 xsd:integer 的 数字, 是有限长度的十进制 数字(0-9)序列,可带可选的前导负号;禁止前导 零。在 JavaScript 中,实现者可以使用以下 代码片段将整数转换为 规范词法 形式:

示例 20:JavaScript 中的整数序列化实现示例
(value).toFixed(0).toString()

double 的规范词法 形式,即 数字 具有非零小数部分或绝对值大于等于 1021, 或被强制为 xsd:double 的 数字, 由尾数后跟字符 E 再后跟指数组成。尾数是 十进制数,指数是整数。指数中禁止前导零和 前置加号(+)。 如果指数为零,则表示为 E0。对于 尾数,禁止前置的可选加号,并且 必须有小数点。禁止前导和尾随零, 但受以下约束:数字表示必须规范化, 使小数点左侧只有一个非零数字,并且 小数点右侧至少有一个数字,除非所表示的值为零。 零的规范表示为 0.0E0。 xsd:double 的值空间由 IEEE 双精度 64 位浮点类型 [IEEE-754-2008] 定义,而 JSON 数字的值空间未 指定;在将 JSON-LD 反序列化为 RDF 时,尾数会舍入到 小数点后 15 位。在 JavaScript 中,实现者 可以使用以下代码片段将 double 转换为 规范词法 形式:

示例 21:JavaScript 中的浮点数序列化 实现示例
(value).toExponential(15).replace(/(\d)0*e\+?/,'$1E')

布尔值 true 和 false 的 规范词法 形式 是字符串 true 和 false。

规范词法形式对于 JSON 字面量而言, 是将内部表示 按照 [RFC8259] 序列化为 JSON 格式的结果,并符合 [JSON-LD11] 中 rdf:JSON 数据类型 的 value space 描述中的约束。

当 JSON 原生数字被反序列化 为 RDF 时,无法保证无损数据往返转换,因为可能发生舍入 错误。在 将 RDF 序列化为 JSON-LD时, 也可能发生类似的舍入错误。此外,数据类型或词法 表示可能会丢失。例如,值为 2.0 的 xsd:double 在从 RDF 转换到 JSON-LD 再转换回 RDF 时,会得到一个值为 2 的 xsd:integer, 且处于规范词法形式。 需要强调的是,实践中可能不可能无损地 将 xsd:integer 转换为 数字,因为 其值空间不受限制。虽然 JSON 规范 [RFC8259] 也没有限制数字的值空间, 但具体实现通常确实具有有限的值空间。

为确保无损往返转换, 将 RDF 序列化为 JSON-LD 算法 指定了一个 useNativeTypes 标志,用于控制 具有等于 xsd:integer、xsd:double 或 xsd:boolean 的 数据类型 IRI 的 RDF 字面量 是否会转换为其 JSON 原生对应项。如果 useNativeTypes 标志设置为 false,所有字面量都会保留其原始字符串 表示。

某些 JSON 序列化器,例如某些版本中的 PHP 原生实现, 会用反斜杠转义正斜杠字符。例如,值 http://example.com/ 会被序列化为 http:\/\/example.com\/。 这是有问题的,因为其他 JSON 解析器可能无法理解这些转义字符。 在 JSON-LD 中无需用反斜杠转义正斜杠。为帮助 JSON-LD 处理器之间实现互操作性,正斜杠 MUST NOT 被 反斜杠转义。

9. 应用程序编程 接口

此 API 提供了一种清晰的机制,使开发者能够将 JSON-LD 数据转换为多种通常更易于 使用的输出格式。

JSON-LD API 使用 Promises 来表示 各种延迟操作的结果。 Promises 定义于 [ECMASCRIPT]。 规范中的一般用法可见于 [promises-guide]。 只要实现通常使用相同的方法、参数和选项 并返回相同结果,实现 MAY 选择以 适合其原生环境的方式来实现。

注

接口标记为 [Exposed=JsonLd], 这会创建一个全局接口。 JSON-LD 中使用 WebIDL 虽然适合在浏览器中使用, 但并不限于这种使用方式。

9.1 JsonLdProcessor 接口

JsonLdProcessor 接口是高级编程 结构, 开发者用它来访问 JSON-LD 转换方法。

需要强调的是,实现不会修改输入参数。 如果检测到错误,Promise 会以带有适当 code 的 JsonLdError 被拒绝, 并且处理会停止。

如果指定了 documentLoader 选项,它会用于解引用远程文档和上下文。 返回的 RemoteDocument 中的 documentUrl 会用作基准 IRI,并且 contextUrl 会被使用,而不是直接查看 HTTP Link Header。为简单起见,本文档中的 算法 均不直接提及这一点。

WebIDL/*
 * The JsonLd interface is created to expose the JsonLdProcessor interface.
 */
[Global=JsonLd, Exposed=JsonLd]
interface JsonLd {};

[Exposed=JsonLd]
interface JsonLdProcessor {
  constructor();
  static Promise<JsonLdRecord> compact(
    JsonLdInput input,
    optional JsonLdContext context = null,
    optional JsonLdOptions options = {});
  static Promise<sequence<JsonLdRecord>> expand(
    JsonLdInput input,
    optional JsonLdOptions options = {});
  static Promise<JsonLdRecord> flatten(
    JsonLdInput input,
    optional JsonLdContext context = null,
    optional JsonLdOptions options = {});
  static Promise<sequence<JsonLdRecord>> fromRdf(
    RdfDataset input,
    optional JsonLdOptions options = {});
  static Promise<RdfDataset> toRdf(
    JsonLdInput input,
    optional JsonLdOptions options = {});
};
compact()

按照压缩算法中的步骤, 使用 context 压缩给定的 input:

最终输出是从 compacted output 派生出的 映射。 如果 compacted output 是 数组,它会被包含在一个 (可能有别名的)@graph 条目中, 其值为 compacted output; 否则,compacted output 会用作 映射结果。 如果 context 不是 null, 则向该映射结果添加一个 @context 条目。

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 如果提供的 input 是 RemoteDocument, 则将 remote document 初始化为 input。
  3. 否则,如果提供的 input 是表示远程文档 IRI 的 字符串, 则等待并使用 LoadDocumentCallback 将其解引用为 remote document,传入 input 作为 url, 并传入 options 中的 extractAllScripts 选项 作为 extractAllScripts。
  4. 将 expanded input 设置为使用 expand() 方法的结果, 该方法使用 remote document, 或者如果没有 remote document,则使用 input 作为 input, 并使用 options, 其中 ordered 设置为 false, 并且 extractAllScripts 默认为 false。
  5. 如果可用,将 context base 设置为 remote document 中的 documentUrl, 否则设置为 options 中的 base 选项。
  6. 如果 context 是一个 具有 @context 条目的 映射, 则将 context 设置为该 条目的值, 否则设置为 context。
  7. 将 active context 初始化为上下文处理算法的结果, 传入一个新的空 context 作为 active context, context 作为 local context, 并且 context base 作为 base URL。
  8. 将 active context 中的 基准 IRI 设置为 options 中的 base 选项(如果已设置); 否则,如果 compactToRelative 选项为 true, 则设置为当前正在处理的文档的 IRI (如果可用); 否则设置为 null。
  9. 将 compacted output 设置为使用 压缩算法的结果, 使用活动上下文, null 作为 active property, expanded input 作为 element, 以及 options 中的 compactArrays 和 ordered 标志。
    1. 如果 compacted output 是空 数组, 则将其替换为新的 映射。
    2. 否则,如果 compacted output 是 数组, 则将其替换为一个新的 映射,该映射具有单个 条目, 其键是 IRI 压缩 @graph 的结果,其值为 compacted output。
    3. 如果 context 不是 null, 则向 compacted output 添加一个 @context 条目,并将其值 设置为提供的 context。
  10. 使用 compacted output 解析 promise, 将 compacted output 从 内部 表示转换为 JSON 序列化。
input
要对其执行压缩的 映射、 映射数组, 或引用要压缩的 JSON-LD 文档的 IRI。
context
在压缩 input时使用的上下文; 它可以通过 映射、 IRI, 或由映射和 IRI组成的数组来指定。
options
一组选项,用于配置这些算法。 例如,这允许设置输入文档的基准 IRI。 JsonLdOptions 类型定义了 默认选项值。
expand()

按照展开算法中的步骤 展开给定的 input:

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 如果提供的 input 是 RemoteDocument, 则将 remote document 初始化为 input。
  3. 否则,如果提供的 input 是表示远程文档 IRI 的 字符串, 则等待并使用 LoadDocumentCallback 将其解引用为 remote document,传入 input 作为 url, 并传入 options 中的 extractAllScripts 选项 作为 extractAllScripts。
  4. 如果 remote document 中的 document 是字符串,则将其转换为 内部 表示。 如果 document 无法转换为 内部 表示, 则拒绝 promise,并传入 loading document failed 错误。
  5. 初始化新的空 active context。 active context 的 基准 IRI 和 原始基准 URL 设置为 remote document 中的 documentUrl(如果可用); 否则设置为 options 中的 base 选项。 如果已设置, options 中的 base 选项会覆盖 基准 IRI。
  6. 如果 options 中的 expandContext 选项已设置, 则使用上下文处理算法 更新 active context, 传入 expandContext 作为 local context, 并传入 active context 中的 原始 基准 URL 作为 base URL。 如果 expandContext 是一个 具有 @context 条目的 映射, 则改为传入该 条目的值作为 local context。
  7. 如果 remote document 具有 contextUrl, 则使用上下文处理算法 更新 active context, 传入 contextUrl 作为 local context, 并传入 contextUrl 作为 base URL。
  8. 将 expanded output 设置为使用 展开算法的结果, 传入 active context, remote document 中的 document,或者如果没有 remote document,则传入 input 作为 element, null 作为 active property, 如果可用,则将 documentUrl 作为 base URL, 否则将 options 中的 base 选项作为 base URL, 并传入 frameExpansion 和 ordered 标志,这些标志来自 options。
    注
    如果没有 remote document, 则 input 是 JsonLdRecord 或 JsonLdRecords 的 sequence, 它们隐式地已经处于 内部表示中。
    1. 如果 expanded output 是一个 仅包含 @graph 条目的 映射, 则将 expanded output 设置为该值。
    2. 如果 expanded output 是 null, 则将 expanded output 设置为空 数组。
    3. 如果 expanded output 不是 数组, 则将 expanded output 设置为仅包含 expanded output 的 数组。
  9. 使用 expanded output 解析 promise, 将 expanded output 从 内部 表示转换为 JSON 序列化。
input
要对其执行展开的 映射、 映射数组, 或引用要展开的 JSON-LD 文档的 IRI。
options
一组选项,用于配置所使用的算法。 例如,这允许设置输入文档的 基准 IRI。 JsonLdOptions 类型定义了 默认选项值。
flatten()

按照扁平化算法中的步骤, 扁平化给定的 input, 并可选地使用提供的 context 压缩它:

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 如果提供的 input 是 RemoteDocument, 则将 remote document 初始化为 input。
  3. 否则,如果提供的 input 是表示远程文档 IRI 的 字符串, 则等待并使用 LoadDocumentCallback 将其解引用为 remote document,传入 input 作为 url, 并传入 options 中的 extractAllScripts 选项 作为 extractAllScripts。
  4. 将 expanded input 设置为使用 expand() 方法的结果, 该方法使用 remote document, 或者如果没有 remote document,则使用 input 作为 input, 并使用 options ,其中 ordered 设置为 false。
  5. 初始化一个空的 identifier map。
  6. 将 flattened output 设置为使用 扁平化算法的结果, 传入 expanded input 作为 element, 以及来自 options 的 ordered 标志。
    1. 如果 context 不是 null, 则将 flattened output 设置为使用 compact() 方法的结果, 该方法使用 flattened output 作为 input、 context, 以及 options。 将 active context 中的 基准 IRI 设置为 options 中的 base 选项 (如果已设置); 否则,如果 compactToRelative 选项为 true, 则设置为当前正在处理的文档的 IRI (如果可用); 否则设置为 null。
  7. 使用 flattened output 解析 promise, 将 flattened output 从 内部 表示转换为 JSON 序列化, 如有必要。
input
要进行扁平化的 映射、 映射数组, 或引用要扁平化的 JSON-LD 文档的 IRI。
context
在压缩已扁平化的 expanded input 时使用的上下文; 它可以通过 映射、 IRI,或由 映射 和 IRI组成的数组来指定。 如果为 null,则结果不会被压缩,而会保持展开形式。
options
一组选项,用于配置所使用的算法。 例如,这允许设置输入文档的 基准 IRI。 JsonLdOptions 类型定义了 默认选项值。
fromRdf()

按照将 RDF 序列化为 JSON-LD 算法中的步骤,将给定的 input 转换为JSON-LD 文档,并采用 展开形式:

注

此接口并未定义从任意输入创建 RdfDataset 的方式,除了 toRdf() 方法之外。

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 将 expanded result 设置为调用 将 RDF 序列化为 JSON-LD 算法方法 的结果,使用 dataset 和 options。
  3. 使用 expanded result 解析 promise, 将 expanded result 从 内部 表示转换为 JSON 序列化。
input
要进行扁平化的 映射、 映射数组, 或引用要扁平化的 JSON-LD 文档的 IRI。
options
一组选项,用于配置所使用的算法。 例如,这允许设置输入文档的 基准 IRI。 JsonLdOptions 类型定义了 默认选项值。
toRdf()

按照将 JSON-LD 反序列化为 RDF 算法中的步骤,将给定的 input 转换为 RdfDataset:

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 将 expanded input 设置为使用 expand() 方法的结果, 该方法使用 input 和 options ,其中 ordered 设置为 false。
  3. 创建一个新的 RdfDataset dataset。
  4. 创建一个新的映射 node map。
  5. 调用节点映射生成算法, 传入 expanded input 作为 element 并传入 node map。
  6. 调用将 JSON-LD 反序列化为 RDF 算法, 传入 node map、dataset, 以及来自 options 的 produceGeneralizedRdf 标志。
    注
    使用空白 节点标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除, 对广义 RDF 数据集的支持也是如此, 因而 produceGeneralizedRdf 选项 也可能被移除。
  7. 使用 dataset 解析 promise。
input
要进行扁平化的 映射、 映射数组, 或引用要扁平化的 JSON-LD 文档的 IRI。
options
一组选项,用于配置所使用的算法。 例如,这允许设置输入文档的 基准 IRI。 JsonLdOptions 类型定义了 默认选项值。
WebIDLtypedef record<USVString, any> JsonLdRecord;

JsonLdRecord 是一个映射的定义, 用于包含任意映射 条目, 这些条目是解析 JSON 对象的结果。

WebIDLtypedef (JsonLdRecord or sequence<JsonLdRecord> or USVString or RemoteDocument) JsonLdInput;

JsonLdInput 接口用于指代 一个输入值, 该值可以是 JsonLdRecord、 JsonLdRecords 的 sequence、 表示 IRI 的 字符串, 该 IRI 可以被解引用以获取有效的 JSON 文档, 或者已经解引用的 RemoteDocument。

当值是 JsonLdRecord 或 JsonLdRecords 的 sequence 时, 这些值会被视为其等价的内部表示值, 其中 JsonLdRecord 等价于一个 映射, 而 JsonLdRecords 的 sequence 等价于一个由 映射组成的 数组。这些 映射条目会被转换为 其在 [INFRA] 中的等价项。

WebIDLtypedef (JsonLdRecord or sequence<(JsonLdRecord or USVString)> or USVString) JsonLdContext;

JsonLdContext 接口用于 指代一个值, 该值可以是 JsonLdRecord、 JsonLdRecords 的 sequence, 或表示 IRI 的 字符串, 该 IRI 可以被解引用以获取有效的 JSON 文档。

当值是 JsonLdRecord 或 JsonLdRecords 的 sequence 时, 这些值会被视为其等价的内部表示值, 其中 JsonLdRecord 等价于一个 映射, 而 JsonLdRecords 的 sequence 等价于一个由 映射组成的 数组。这些 映射条目会被转换为 其在 [INFRA] 中的等价项。

9.2 RDF 数据集接口

RdfDataset 接口描述对 一个 RDF 数据集 的操作,该数据集由 JsonLdProcessor 接口中的 fromRdf() 和 toRdf() 方法使用。 该接口可用于构造新的 RDF 数据集, 它具有一个可通过 defaultGraph 属性访问的 默认图。

WebIDL[Exposed=JsonLd]
interface RdfDataset {
  constructor();
  readonly attribute RdfGraph defaultGraph;
  void add(USVString graphName, RdfGraph graph);
  iterable<USVString?, RdfGraph>;
};
add()

向 RdfDataset 添加一个 RdfGraph 及其关联的图名。 由将 JSON-LD 反序列化为 RDF 算法使用。

graphName
与 graph 关联的 图名。 graphName MUST 是一个 格式良好的 IRI 或 空白节点 标识符。
graph
要添加到 RdfDataset 的 RdfGraph。
defaultGraph
提供对与 RDF 数据集关联的 默认图的访问。
iterable
要迭代的值对 是 graph name-graph 对的列表, 其中 graph name 为 null (用于默认图)、 IRI, 或空白节点标识符, 而 graph 是一个 RdfGraph 实例。

RdfGraph 接口描述对 RDF 图的操作, 该图由 JsonLdProcessor 接口中的 fromRdf() 和 toRdf() 方法使用。 该接口可用于构造新的 RDF 图, 它由零个或多个 RdfTriple 实例组成。

WebIDL[Exposed=JsonLd]
interface RdfGraph {
  constructor();
  void add(RdfTriple triple);
  iterable<RdfTriple>;
};
add()

向 RdfGraph 添加一个 RdfTriple。 由将 JSON-LD 反序列化为 RDF 算法使用。

triple
要添加到 RdfGraph 的 RdfTriple。
iterable
一个值迭代器, 用于遍历与该图关联的 RdfTriple 实例。 注意,在特定 RdfDataset 实例中, 给定的 RdfTriple 实例可能出现在多个图中。

RdfTriple 接口描述一个 三元组。

WebIDL[Exposed=JsonLd]
interface RdfTriple {
  constructor();
  readonly attribute USVString subject;
  readonly attribute USVString predicate;
  readonly attribute (USVString or RdfLiteral) _object;
};
subject
表示该 三元组的 主语的绝对 IRI 或 空白节点标识符。
predicate
表示该 三元组的 谓词的绝对 IRI。 如果用于表示 广义 RDF 数据集, 它也可以是 空白节点 标识符。
注
使用空白节点 标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除,对 广义 RDF 数据集的支持也是如此。
object
表示该 三元组的 宾语的绝对 IRI、 空白节点 标识符,或 字面量。

RdfLiteral 接口描述一个 RDF 字面量。

WebIDL[Exposed=JsonLd]
interface RdfLiteral {
  constructor();
  readonly attribute USVString value;
  readonly attribute USVString datatype;
  readonly attribute USVString? language;
};
value
字面量的词法值。
datatype
表示该字面量的 数据类型 IRI的绝对 IRI。 如果值为 rdf:langString, 则 language MUST 被指定。
language
一个可选的 语言标签,如 [BCP47] 所定义。 如果指定了该值,datatype MUST 为 rdf:langString。

9.3 JsonLdOptions 类型

JsonLdOptions 类型用于向 JsonLdProcessor 方法传递各种选项。

WebIDLdictionary JsonLdOptions {
  USVString?             base = null;
  boolean                compactArrays = true;
  boolean                compactToRelative = true;
  LoadDocumentCallback?  documentLoader = null;
  (JsonLdRecord? or USVString) expandContext = null;
  boolean                extractAllScripts = false;
  boolean                frameExpansion = false;
  boolean                ordered = false;
  USVString              processingMode = "json-ld-1.1";
  boolean                produceGeneralizedRdf = true;
  USVString?             rdfDirection = null;
  boolean                useNativeTypes = false;
  boolean                useRdfType = false;
};
base
展开或压缩文档时要使用的基准 IRI。 如果设置,它会覆盖输入文档的 IRI。
compactArrays
如果设置为 true,JSON-LD 处理器会在 压缩期间将只有一个元素的数组替换为该元素。 如果设置为 false, 所有数组都将保持为数组,即使它们只有一个元素。
compactToRelative
确定在压缩时,IRI 是否相对于 base 选项 或文档位置进行压缩。
documentLoader
用于检索远程文档和上下文的加载器回调, 实现 LoadDocumentCallback。 如果指定,则用于检索远程文档和上下文; 否则,如果未指定,则使用处理器的内置加载器。
expandContext
在展开文档时用于初始化活动上下文的上下文。
extractAllScripts
如果设置为 true, 当从 HTML 中提取 JSON-LD script 元素时, 除非目标是特定 片段标识符, 否则会使用数组形式(如有必要) 提取所有遇到的 JSON-LD script 元素。
frameExpansion
为展开算法启用特殊的框架处理规则。
为将 RDF 序列化为 JSON-LD 算法启用特殊规则, 以尽可能使用 JSON-LD 原生类型作为值。
ordered
如果设置为 true, 某些注明的算法处理步骤会按字典序排列。 如果为 false,处理时不考虑顺序。
processingMode
设置处理模式。 如果设置为 json-ld-1.0 或 json-ld-1.1, 实现必须产生与本规范中定义的算法完全相同的结果。 如果设置为其他值, 则允许 JSON-LD 处理器扩展或修改本规范中定义的算法, 以启用特定于应用的优化。 此类优化的定义超出本规范范围, 因而未作定义。 因此,不同实现可能实现不同的优化。 开发者不得定义以 json-ld 开头的模式, 因为它们为本规范的未来版本保留。
produceGeneralizedRdf
如果设置为 true,JSON-LD 处理器可以为 三元组的 谓词 发出空白节点; 否则它们将被省略。 广义 RDF 数据集 定义于 [RDF11-CONCEPTS]。
注
使用空白节点 标识符标记属性已过时, 并可能在 JSON-LD 的未来版本中移除, 对广义 RDF 数据集的支持也是如此, 因而 produceGeneralizedRdf 选项 也可能被移除。
rdfDirection
确定包含 基准方向的 值对象如何与 RDF 相互转换。
  • 如果设置为 i18n-datatype,则使用基于 https://www.w3.org/ns/i18n# 的数据类型 IRI 生成 RDF 字面量, 其中同时编码语言标签(如果存在) 和基准方向。 从 RDF 转换时,会解码此数据类型以创建包含 @language(如果存在)和 @direction 的 值对象。
  • 如果设置为 compound-literal,则发出一个 空白节点, 而不是字面量; 其中该空白节点是 rdf:value、rdf:direction 和 rdf:language(如果存在)属性的主语。 从 RDF 转换时,会解码此对象以创建包含 @language(如果存在)和 @direction 的 值对象。
useNativeTypes
使将 RDF 序列化为 JSON-LD 算法 在值对象中使用原生 JSON 值, 从而避免显式 @type 的需要。
useRdfType
为将 RDF 序列化为 JSON-LD 算法 启用特殊规则, 使 rdf:type 属性在输出中保留为 IRI,而不是使用 @type。

9.4 远程文档和上下文 检索

API 实现的用户可以利用回调来控制 如何检索远程文档和上下文。 本节详细说明该回调的参数 以及用于返回已检索上下文的数据结构。

9.4.1 LoadDocumentCallback

LoadDocumentCallback 定义了自定义文档加载器 必须实现的回调,以用于检索远程文档和上下文。 该回调返回一个解析为 RemoteDocument 的 Promise。 失败时,该 Promise 会以带有适当错误 code 的 JsonLdError 被拒绝。

WebIDLcallback LoadDocumentCallback = Promise<RemoteDocument> (
  USVString url,
  optional LoadDocumentOptions? options
);
url
要加载的远程文档或上下文的 URL。
options
用于确定回调行为的一组选项。参见 § 9.4.2 LoadDocumentOptions。

以下算法描述默认回调,并对回调实现提出要求。

  1. 创建一个新的 Promise promise 并返回它。 随后延迟执行以下步骤。
  2. 将 document 设置为从 url 标识的资源中检索到的主体, 或通过其他方式定位与 url 关联的资源。 请求远程文档时,请求 MUST 优先选择 Content-Type application/ld+json, 其次是 application/json。

    如果设置了 requestProfile, 它 MUST 作为 application/ld+json 上的 profile 添加。

    处理器 MAY 包含其他使用 +json 后缀的媒体类型,如 [RFC6839] 中定义。

  3. 将 documentUrl 设置为所检索资源的位置, 并考虑重定向(不包括 HTTP 状态 303 “See Other” 重定向, 如 [cooluris] 中所讨论)。
  4. 如果所检索资源的 Content-Type 既不是 application/json, 也不是 [RFC6839] 中定义的任何带 +json 后缀的媒体类型, 并且响应具有使用 alternate 链接关系且类型为 application/ld+json 的 HTTP Link Header [RFC8288], 则将 url 设置为关联的 href(相对于先前的 url), 并从步骤 2重新开始算法。
  5. 如果所检索资源的 Content-Type 是 application/json 或 [RFC6839] 中定义的任何带 +json 后缀的媒体类型, 但不包括 application/ld+json, 并且响应具有使用 http://www.w3.org/ns/json-ld#context 链接关系的 HTTP Link Header [RFC8288], 则将 contextUrl 设置为关联的 href。

    如果发现多个使用 http://www.w3.org/ns/json-ld#context 链接关系的 HTTP Link Header, 则以 JsonLdError 拒绝 promise, 其 code 设置为 multiple context link headers, 并终止处理。

    处理器 MAY 将 document 转换为 内部 表示。

    注

    对于以 application/ld+json、 text/html 或 application/xhtml+xml 提供的文档, HTTP Link Header 会被忽略。

  6. 否则,所检索文档的 Content-Type 既不是 application/json, 也不是 application/ld+json, 也不是 [RFC6839] 中定义的任何其他使用 +json 后缀的媒体类型。 拒绝 promise,并传入 loading document failed 错误。
  7. 使用 url 作为 documentUrl, document 作为 document, 返回的Content-Type(不含参数) 作为 contentType, 任何返回的 profile 参数或 null 作为 profile, 并以 contextUrl 或 null 作为 contextUrl, 创建一个新的 RemoteDocument remote document。
  8. 使用 remote document 解析 promise。
注

通过 documentLoader 选项设置的自定义 LoadDocumentCallback 可能用于维护众所周知上下文文档的本地缓存,或实现 特定于应用的 URL 协议。

9.4.2 LoadDocumentOptions

LoadDocumentOptions 类型 用于向 LoadDocumentCallback 传递各种选项。

WebIDLdictionary LoadDocumentOptions {
  boolean  extractAllScripts = false;
  USVString profile = null;
  (USVString or sequence<USVString>) requestProfile = null;
};
extractAllScripts
如果设置为 true, 当从 HTML 中提取 JSON-LD script 元素时, 除非目标是特定 片段 标识符, 否则会使用数组形式(如有必要) 提取所有遇到的 JSON-LD script 元素。
profile
当生成的 contentType 为 text/html 或 application/xhtml+xml 时, 此选项确定用于选择 JSON-LD script 元素的 profile。
requestProfile
一个或多个 IRI,用作请求中的 profile 参数。 (参见 [JSON-LD11] 中的 IANA 注意事项。)

9.4.3 RemoteDocument

RemoteDocument 类型由 LoadDocumentCallback 用于返回有关远程文档或上下文的信息。

WebIDL[Exposed=JsonLd]
interface RemoteDocument {
  constructor();
  readonly attribute USVString contentType;
  readonly attribute USVString contextUrl;
  attribute any document;
  readonly attribute USVString documentUrl;
  readonly attribute USVString profile;
};
contentType
已加载文档的 Content-Type, 不包括任何可选参数。
contextUrl
如果可用,表示响应中使用 http://www.w3.org/ns/json-ld#context 链接关系的 HTTP Link Header [RFC8288] 的值。 如果响应的 Content-Type 是 application/ld+json, 则忽略 HTTP Link Header。 如果发现多个使用 http://www.w3.org/ns/json-ld#context 链接 关系的 HTTP Link Header, 则 LoadDocumentCallback 的 Promise 会以 JsonLdError 被拒绝, 其 code 设置为 multiple context link headers。
document
检索到的文档。 这可以是原始负载,也可以是已经解析的文档。
documentUrl
已加载文档的最终 URL。 这对于正确处理 HTTP 重定向很重要。
profile
作为原始 contentType 的一部分检索到的任何 profile 参数的值。

9.5 HTML 内容算法

注

本节描述在支持 HTML script 提取的 documentLoader 中可用的可选特性。

documentLoader 的实现 MAY 支持从 HTML [HTML] 文档中包含的 script 元素 提取 JSON-LD。 本节描述此类处理器的规范行为。 这样的处理器支持 HTML script 提取。

9.5.1 处理 HTML

本节描述对 LoadDocumentCallback 中指定的算法的扩展, 以支持从 HTML 中提取 JSON-LD。

步骤 2 更新为添加以下内容:支持 HTML script 提取的处理器 MUST 在任何偏好级别包含 text/html, 并且 MAY 在任何偏好级别包含 application/xhtml+xml, 除非 requestProfile 是 http://www.w3.org/ns/json-ld#context。

在步骤 5之后,添加以下处理步骤: 否则,如果所检索资源的 Content-Type 是 text/html 或 application/xhtml+xml:

  1. 将 documentUrl 设置为 Document Base URL, 该 URL 属于 url,如 [HTML] 中所定义, 并使用现有的 documentUrl 作为文档的 URL。
  2. 如果 url 参数 包含片段标识符, 则将 source 设置为 document 中 script 元素的 textContent, 该元素具有与片段标识符匹配的 id 属性, 匹配前先解码 百分号编码序列。

    如果未找到这样的元素, 或找到的元素不是 JSON-LD script 元素, 则以 JsonLdError 拒绝 promise, 其 code 设置为 loading document failed, 并终止处理。

  3. 否则,如果指定了 profile 选项, 则将 source 设置为转换 document 中第一个 script 元素的 textContent 的结果, 该元素具有 application/ld+json 的 type 属性, 并带有 profile 选项的值(如果找到)。
  4. 如果 source 仍未定义,并且 extractAllScripts 选项不存在或为 false, 则将 source 设置为 document 中第一个 JSON-LD script 元素的 textContent。

    如果未找到这样的元素, 或找到的元素不是 JSON-LD script 元素, 则以 JsonLdError 拒绝 promise, 其 code 设置为 loading document failed, 并终止处理。

  5. 如果 source 已定义, 则将 document 设置为 提取脚本内容算法的结果, 使用 source,如果检测到错误, 则以 JsonLdError 拒绝 promise, 其 code 从结果设置, 并终止处理。
  6. 否则,source 未定义。
    1. 如果 extractAllScripts 选项不存在或为 false, 则以 JsonLdError 拒绝 promise, 其 code 设置为 loading document failed, 并终止处理。
    2. 否则,extractAllScripts 选项为 true。 将 document 设置为新的空 数组。 对于 input 中的每个 JSON-LD script 元素:
      1. 将 source 设置为其 textContent。
      2. 将 script content 设置为 提取脚本内容算法的结果, 使用 source,如果检测到错误, 则以 JsonLdError 拒绝 promise,其 code 从结果设置, 并终止处理。
      3. 如果 script content 是 数组,则将其合并到 document 的末尾。
      4. 否则,将 script content 追加到 document。

9.5.2 提取脚本内容 算法

该算法将 JSON-LD script 元素的文本内容提取为 映射或由 映射组成的 数组。 JSON-LD script 元素是 HTML [HTML] 文档中的 script 元素, 其 type 属性 设置为 application/ld+json。

该算法接受一个必需输入变量:source, 即 HTML script 元素的 textContent。

  1. 如果 source 不是有效的 JSON 文档, 则检测到 invalid script element,并中止处理。
  2. 返回将 source 转换为 内部 表示的结果。

9.6 错误处理

本节描述 JSON-LD API 中用于错误处理的数据类型定义。

9.6.1 JsonLdError

JsonLdError 类型用于报告 处理错误。

WebIDLdictionary JsonLdError {
  JsonLdErrorCode code;
  USVString?      message = null;
};
code
表示特定错误类型的字符串, 如本文档中各算法所述。
message
包含附加调试信息的可选错误消息。 错误消息的具体内容超出本规范范围。

9.6.2 JsonLdErrorCode

JsonLdErrorCode 表示有效 JSON-LD 错误代码的集合。

WebIDLenum JsonLdErrorCode {
    "colliding keywords",
    "conflicting indexes",
    "context overflow",
    "cyclic IRI mapping",
    "invalid @id value",
    "invalid @import value",
    "invalid @included value",
    "invalid @index value",
    "invalid @nest value",
    "invalid @prefix value",
    "invalid @propagate value",
    "invalid @protected value",
    "invalid @reverse value",
    "invalid @version value",
    "invalid base direction",
    "invalid base IRI",
    "invalid container mapping",
    "invalid context entry",
    "invalid context nullification",
    "invalid default language",
    "invalid IRI mapping",
    "invalid JSON literal",
    "invalid keyword alias",
    "invalid language map value",
    "invalid language mapping",
    "invalid language-tagged string",
    "invalid language-tagged value",
    "invalid local context",
    "invalid remote context",
    "invalid reverse property map",
    "invalid reverse property value",
    "invalid reverse property",
    "invalid scoped context",
    "invalid script element",
    "invalid set or list object",
    "invalid term definition",
    "invalid type mapping",
    "invalid type value",
    "invalid typed value",
    "invalid value object value",
    "invalid value object",
    "invalid vocab mapping",
    "IRI confused with prefix",
    "keyword redefinition",
    "loading document failed",
    "loading remote context failed",
    "multiple context link headers",
    "processing mode conflict",
    "protected term redefinition"
};
colliding keywords
检测到两个展开为同一关键字的 属性。 当一个关键字 及其别名同时使用时,可能发生这种情况。
conflicting indexes
为同一节点发现了多个相互冲突的索引。
context overflow
超过了 @context URL 的最大数量。
cyclic IRI mapping
检测到 IRI 映射中的循环。
invalid @id value
遇到了一个 @id 条目,其值不是 字符串。
invalid @import value
发现了 @import 的无效值。
invalid @included value
包含块包含无效值。
invalid @index value
遇到了一个 @index 条目,其值不是 字符串。
invalid @nest value
发现了 @nest 的无效值。
invalid @prefix value
发现了 @prefix 的无效值。
invalid @propagate value
发现了 @propagate 的无效值。
invalid @protected value
发现了 @protected 的无效值。
invalid @reverse value
检测到 @reverse 条目的无效值, 即该值不是映射。
invalid @version value
@version 条目在一个 上下文 中使用了超出范围的值。
invalid base direction
@direction 的值不是 "ltr"、 "rtl" 或 null,因此无效。
invalid base IRI
检测到无效的 基准 IRI,即它既不是 IRI,也不是 null。
invalid container mapping
遇到了一个 @container 条目, 其值不是以下 字符串之一: @list、 @set、 @language、 @index、 @id、 @graph,或 @type。
invalid context entry
上下文中的一个 条目因处理模式不兼容而无效。
invalid context nullification
尝试将包含 受保护 术语 定义的上下文置为 null。
invalid default language
默认语言的值不是 字符串 或 null,因此无效。
invalid IRI mapping
局部 上下文包含一个 术语, 该术语具有无效或缺失的 IRI 映射。
invalid JSON literal
检测到无效的 JSON 字面量。
invalid keyword alias
遇到了无效的 关键字别名定义。
invalid language map value
检测到语言映射中的无效值。 它 MUST 是 字符串,或由 字符串组成的 数组。
invalid language mapping
在 术语定义中遇到了 @language 条目, 其值既不是 字符串 也不是 null,因此无效。
invalid language-tagged string
检测到具有无效语言值的 带语言标签的 字符串。
invalid language-tagged value
检测到带有关联 语言标签的 数字、 true 或 false。
invalid local context
检测到无效的 局部上下文。
invalid remote context
未找到所引用远程上下文的有效上下文文档。
invalid reverse property
检测到无效的反向属性定义。
invalid reverse property map
检测到无效的反向属性映射。 除 @context 外,反向属性映射中不允许出现 关键字。
invalid reverse property value
检测到反向属性的无效值。 逆属性的值必须是 节点对象。
invalid scoped context
在 术语定义 中定义的 局部上下文 无效。
invalid script element
HTML 输入中作为 片段 标识符目标的 script 元素 没有适当的 type 属性。
invalid set or list object
检测到具有不允许的 条目的 集合对象 或 列表 对象。
invalid term definition
检测到无效的 术语定义。
invalid type mapping
在 术语定义中遇到了 @type 条目, 其值无法展开为 IRI。
invalid type value
检测到 @type 条目的无效值, 即该值既不是 字符串,也不是由 字符串组成的 数组。
invalid typed value
检测到具有无效类型的 类型化 值。
invalid value object
检测到具有不允许的 条目的 值 对象。
invalid value object value
检测到 值对象的 @value 条目的无效值, 即它既不是 标量,也不是 null。
invalid vocab mapping
检测到无效的 词汇表映射, 即它既不是 IRI,也不是 null。
IRI confused with prefix
压缩一个 IRI会得到一个可能与 紧凑 IRI 混淆的 IRI 时(因为它的 IRI 方案匹配一个 术语 定义,且它没有 IRI 权威部分)。
keyword redefinition
检测到 关键字 重定义。
loading document failed
无法加载文档或无法将其解析为 JSON。
loading remote context failed
加载远程上下文时遇到问题。
multiple context link headers
检测到多个使用 http://www.w3.org/ns/json-ld#context 链接关系的 HTTP Link Header [RFC8288]。
processing mode conflict
尝试更改与先前指定版本不兼容的 处理模式。
protected term redefinition
尝试重定义一个 受保护术语。

10. 安全注意事项

参见 [JSON-LD11] 中的 安全注意事项。

11. 隐私注意事项

参见 [JSON-LD11] 中的 隐私注意事项。

12. 国际化 注意事项

参见 [JSON-LD11] 中的 国际化注意事项。

A. IDL 索引

本节是非规范性的。

WebIDL/*
 * The JsonLd interface is created to expose the JsonLdProcessor interface.
 */
[Global=JsonLd, Exposed=JsonLd]
interface JsonLd {};

[Exposed=JsonLd]
interface JsonLdProcessor {
  constructor();
  static Promise<JsonLdRecord> compact(
    JsonLdInput input,
    optional JsonLdContext context = null,
    optional JsonLdOptions options = {});
  static Promise<sequence<JsonLdRecord>> expand(
    JsonLdInput input,
    optional JsonLdOptions options = {});
  static Promise<JsonLdRecord> flatten(
    JsonLdInput input,
    optional JsonLdContext context = null,
    optional JsonLdOptions options = {});
  static Promise<sequence<JsonLdRecord>> fromRdf(
    RdfDataset input,
    optional JsonLdOptions options = {});
  static Promise<RdfDataset> toRdf(
    JsonLdInput input,
    optional JsonLdOptions options = {});
};

typedef record<USVString, any> JsonLdRecord;

typedef (JsonLdRecord or sequence<JsonLdRecord> or USVString or RemoteDocument) JsonLdInput;

typedef (JsonLdRecord or sequence<(JsonLdRecord or USVString)> or USVString) JsonLdContext;

[Exposed=JsonLd]
interface RdfDataset {
  constructor();
  readonly attribute RdfGraph defaultGraph;
  void add(USVString graphName, RdfGraph graph);
  iterable<USVString?, RdfGraph>;
};

[Exposed=JsonLd]
interface RdfGraph {
  constructor();
  void add(RdfTriple triple);
  iterable<RdfTriple>;
};

[Exposed=JsonLd]
interface RdfTriple {
  constructor();
  readonly attribute USVString subject;
  readonly attribute USVString predicate;
  readonly attribute (USVString or RdfLiteral) _object;
};

[Exposed=JsonLd]
interface RdfLiteral {
  constructor();
  readonly attribute USVString value;
  readonly attribute USVString datatype;
  readonly attribute USVString? language;
};

dictionary JsonLdOptions {
  USVString?             base = null;
  boolean                compactArrays = true;
  boolean                compactToRelative = true;
  LoadDocumentCallback?  documentLoader = null;
  (JsonLdRecord? or USVString) expandContext = null;
  boolean                extractAllScripts = false;
  boolean                frameExpansion = false;
  boolean                ordered = false;
  USVString              processingMode = "json-ld-1.1";
  boolean                produceGeneralizedRdf = true;
  USVString?             rdfDirection = null;
  boolean                useNativeTypes = false;
  boolean                useRdfType = false;
};

callback LoadDocumentCallback = Promise<RemoteDocument> (
  USVString url,
  optional LoadDocumentOptions? options
);

dictionary LoadDocumentOptions {
  boolean  extractAllScripts = false;
  USVString profile = null;
  (USVString or sequence<USVString>) requestProfile = null;
};

[Exposed=JsonLd]
interface RemoteDocument {
  constructor();
  readonly attribute USVString contentType;
  readonly attribute USVString contextUrl;
  attribute any document;
  readonly attribute USVString documentUrl;
  readonly attribute USVString profile;
};

dictionary JsonLdError {
  JsonLdErrorCode code;
  USVString?      message = null;
};

enum JsonLdErrorCode {
    "colliding keywords",
    "conflicting indexes",
    "context overflow",
    "cyclic IRI mapping",
    "invalid @id value",
    "invalid @import value",
    "invalid @included value",
    "invalid @index value",
    "invalid @nest value",
    "invalid @prefix value",
    "invalid @propagate value",
    "invalid @protected value",
    "invalid @reverse value",
    "invalid @version value",
    "invalid base direction",
    "invalid base IRI",
    "invalid container mapping",
    "invalid context entry",
    "invalid context nullification",
    "invalid default language",
    "invalid IRI mapping",
    "invalid JSON literal",
    "invalid keyword alias",
    "invalid language map value",
    "invalid language mapping",
    "invalid language-tagged string",
    "invalid language-tagged value",
    "invalid local context",
    "invalid remote context",
    "invalid reverse property map",
    "invalid reverse property value",
    "invalid reverse property",
    "invalid scoped context",
    "invalid script element",
    "invalid set or list object",
    "invalid term definition",
    "invalid type mapping",
    "invalid type value",
    "invalid typed value",
    "invalid value object value",
    "invalid value object",
    "invalid vocab mapping",
    "IRI confused with prefix",
    "keyword redefinition",
    "loading document failed",
    "loading remote context failed",
    "multiple context link headers",
    "processing mode conflict",
    "protected term redefinition"
};

B. 未解决议题

本节是非规范性的。

以下是在发布时仍处于开放状态的议题列表。

Issue 76:更紧凑的 @prefix defer-future-version

更紧凑的 @prefix。

Issue 94:Expansion 概念 “key's term definition” 对紧凑 IRI 键而言不清楚 defer-future-version

Expansion 概念 “key's term definition” 对紧凑 IRI 键而言不清楚。

Issue 166:与 RDF/JS Dataset 接口的关系 defer-future-version

与 RDF/JS Dataset 接口的关系。

Issue 380: Expansion 未考虑嵌套属性的属性作用域上下文 defer-future-versionspec:editorialtest:needs testswr:spec-updated-partial

Expansion 未考虑嵌套属性的属性作用域上下文。

Issue 391:递归嵌套属性与 压缩 defer-future-version

递归嵌套属性与压缩。

相对 iri 压缩。

C. 自 2014 年 1 月 16 日 1.0 推荐标准以来的变更

本节是非规范性的。

此外,参见 § D. 自 JSON-LD 社区组最终报告以来的变更。

D. 自 JSON-LD 社区组最终报告以来的变更

本节是非规范性的。

E. 自 2019 年 12 月 12 日候选发布以来的变更

本节是非规范性的。

注

所有变更都是编辑性的,不影响 API 的可观察行为, 也不影响预期的测试结果。

F. 自 2020 年 3 月 5 日 候选发布以来的变更

本节是非规范性的。

注

所有变更都是编辑性的,不影响 API 的可观察行为, 也不影响预期的测试结果。

G. 自 2020 年 5 月 7 日提议推荐标准发布以来的变更

本节是非规范性的。

H. 致谢

本节是非规范性的。

编辑们特别感谢以下个人对本规范的撰写和编辑作出了重要贡献:

此外,以下人员在发布时是工作组成员:

还要衷心感谢 JSON-LD 社区组的参与者, 他们通过邮件列表和每周电话会议解决了许多技术问题:Chris Webber、David Wood、Drummond Reed、Eleanor Joslin、Fabien Gandon、Herm Fisher、Jamie Pitts、Kim Hamilton Duffy、Niklas Lindström、Paolo Ciccarese、Paul Frazze、Paul Warren、Reto Gmür、Rob Trainer、Ted Thibodeau Jr. 和 Victor Charpenay。

I. 参考文献

I.1 规范性参考文献

[BCP47]
Tags for Identifying Languages. A. Phillips; M. Davis. IETF. 2009 年 9 月。IETF 当前最佳实践。URL: https://tools.ietf.org/html/bcp47
[DOM]
DOM Standard. Anne van Kesteren. WHATWG. 现行标准。URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 现行标准。URL: https://html.spec.whatwg.org/multipage/
[IEEE-754-2008]
IEEE 754-2008 Standard for Floating-Point Arithmetic. Institute of Electrical and Electronics Engineers. 2008. URL: http://standards.ieee.org/findstds/standard/754-2008.html
[INFRA]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. 现行标准。URL: https://infra.spec.whatwg.org/
[JSON-LD10]
JSON-LD 1.0. Manu Sporny; Gregg Kellogg; Marcus Langhaler. W3C. 2014 年 1 月 16 日。W3C 推荐标准。URL: https://www.w3.org/TR/2014/REC-json-ld-20140116/
[JSON-LD11]
JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 2020 年 5 月 7 日。W3C 提议推荐标准。URL: https://www.w3.org/TR/json-ld11/
[JSON-LD11-FRAMING]
JSON-LD 1.1 Framing. Dave Longley; Gregg Kellogg; Pierre-Antoine Champin. W3C. 2020 年 5 月 7 日。W3C 提议推荐标准。URL: https://www.w3.org/TR/json-ld11-framing/
[LINKED-DATA]
Linked Data Design Issues. Tim Berners-Lee. W3C. 2006 年 7 月 27 日。W3C 内部文档。URL: https://www.w3.org/DesignIssues/LinkedData.html
[promises-guide]
Writing Promise-Using Specifications. Domenic Denicola. W3C. 2018 年 11 月 9 日。TAG 发现。URL: https://www.w3.org/2001/tag/doc/promises-guide
[RDF-SCHEMA]
RDF Schema 1.1. Dan Brickley; Ramanathan Guha. W3C. 2014 年 2 月 25 日。W3C 推荐标准。URL: https://www.w3.org/TR/rdf-schema/
[RDF11-CONCEPTS]
RDF 1.1 Concepts and Abstract Syntax. Richard Cyganiak; David Wood; Markus Lanthaler. W3C. 2014 年 2 月 25 日。 W3C 推荐标准。URL: https://www.w3.org/TR/rdf11-concepts/
[RDF11-MT]
RDF 1.1 Semantics. Patrick Hayes; Peter Patel-Schneider. W3C. 2014 年 2 月 25 日。W3C 推荐标准。URL: https://www.w3.org/TR/rdf11-mt/
[RFC2045]
Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies. N. Freed; N. Borenstein. IETF. 1996 年 11 月。草案标准。URL: https://tools.ietf.org/html/rfc2045
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. 1997 年 3 月。当前最佳实践。URL: https://tools.ietf.org/html/rfc2119
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005 年 1 月。互联网 标准。URL: https://tools.ietf.org/html/rfc3986
[RFC3987]
Internationalized Resource Identifiers (IRIs). M. Duerst; M. Suignard. IETF. 2005 年 1 月。提议标准。URL: https://tools.ietf.org/html/rfc3987
[RFC5234]
Augmented BNF for Syntax Specifications: ABNF. D. Crocker, Ed.; P. Overell. IETF. 2008 年 1 月。互联网标准。URL: https://tools.ietf.org/html/rfc5234
[RFC6839]
Additional Media Type Structured Syntax Suffixes. T. Hansen; A. Melnikov. IETF. 2013 年 1 月。资料性。URL: https://tools.ietf.org/html/rfc6839
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. 2017 年 5 月。当前最佳实践。URL: https://tools.ietf.org/html/rfc8174
[RFC8259]
The JavaScript Object Notation (JSON) Data Interchange Format. T. Bray, Ed.. IETF. 2017 年 12 月。互联网标准。URL: https://tools.ietf.org/html/rfc8259
[RFC8288]
Web Linking. M. Nottingham. 2017 年 10 月。提议标准。URL: https://tools.ietf.org/html/rfc8288
[Turtle]
RDF 1.1 Turtle. Eric Prud'hommeaux; Gavin Carothers. W3C. 2014 年 2 月 25 日。W3C 推荐标准。URL: https://www.w3.org/TR/turtle/
[WEBIDL]
Web IDL. Boris Zbarsky. W3C. 2016 年 12 月 15 日。W3C 编辑草案。URL: https://heycam.github.io/webidl/
[XMLSCHEMA11-2]
W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron et al. W3C. 2012 年 4 月 5 日。W3C 推荐标准。URL: https://www.w3.org/TR/xmlschema11-2/

I.2 资料性参考文献

[cooluris]
Cool URIs for the Semantic Web. Leo Sauermann; Richard Cyganiak. W3C. 2008 年 12 月 3 日。W3C 说明。URL: https://www.w3.org/TR/cooluris/
[JSON-LD10-API]
JSON-LD 1.0 Processing Algorithms And API. Marcus Langhaler; Gregg Kellogg; Manu Sporny. W3C. 2014 年 1 月 16 日。W3C 推荐标准。URL: https://www.w3.org/TR/2014/REC-json-ld-api-20140116/
[RFC8785]
JSON Canonicalization Scheme (JCS). A. Rundgren; B. Jordan; S. Erdtman. Network Working Group. 2020 年 6 月。 资料性。URL: https://www.rfc-editor.org/rfc/rfc8785