YAML作为JSON超集和TAB字符

Vla*_*ged 11 whitespace tabs json yaml

我无法准确找到对此错误的引用,但是YAML 1.2说它是JSON超集,如果我在JSON中使用制表符,则会将其视为错误.

例如

"root": {
        "key": "value"
}
Run Code Online (Sandbox Code Playgroud)

(这里的在线验证说明了'\t' that cannot start any token)

我知道为什么YAML历史上不允许使用制表符,但我怎样才能在JSON-superset的上下文中解释它?

(例如,YAML不是实际超集还是JSON也不允许使用标签?或者规范在这种情况下允许标签,但实现还没有?)

谢谢.

jma*_*777 9

我知道为什么YAML历史上不允许使用制表符,但我怎样才能在JSON-superset的上下文中解释它?

考虑到其余的规范,我们只能得出"超集"评论不准确的结论.YAML规范在与JSON关系部分基本上不一致:

因此,YAML可以被视为JSON的自然超集,提供改进的人类可读性和更完整的信息模型.在实践中也是如此; 每个JSON文件也是有效的YAML文件.如果/当需要其他功能时,这使得从JSON迁移到YAML变得容易.

JSON的RFC4627要求映射键只是"应该"是唯一的,而YAML坚持认为它们"必须".从技术上讲,YAML因此符合JSON规范,选择将重复项视为错误.实际上,由于JSON对此类重复项的语义保持沉默,因此唯一可移植的JSON文件是具有唯一键的文件,因此它们是有效的YAML文件.

尽管声称YAML是"JSON的自然超集"并且声明"每个JSON文件也是一个有效的YAML文件",但规范立即指出了关于密钥唯一性的一些差异.可以说,规范也应该注意在这里使用标签进行缩进的差异.

说到这一点,正如验证者暗示的那样,YAML明确禁止制表符作为缩进字符:

为了保持可移植性,不得在缩进中使用制表符,因为不同的系统会以不同方式处理制表符.请注意,可以配置大多数现代编辑器,以便按Tab键导致插入适当数量的空格.

当然,这比JSON规范更严格,JSON规范简单地声明:

可以在任何一对令牌之间插入空格.

那么,直接回答你的问题......

(例如,YAML不是实际超集还是JSON也不允许使用标签?或者规范在这种情况下允许标签,但实现还没有?)

... YAML实际上不是一个超集,JSON并没有禁止标签,而YAML规范确实不允许标签明确.

  • @BrandonBonds这很有意思.那么,最好的情况是,YAML规范似乎与自身不一致.我不确定如何协调诸如"一般来说,缩进被定义为行开头的零个或多个空格字符"和"为了保持可移植性,不得在缩进中使用制表符"这样的语句,并带有措辞你引用了,尽管它们属于同一规范. (2认同)

jor*_*ker 8

YAML中允许使用选项卡,但仅限于缩进不适用的情况.

根据YAML 1.2第5.5节:

YAML识别两个空格字符:空格制表符.

以下示例将用于·表示空格和?表示制表符.所有示例都可以使用官方YAML Reference Parser进行验证.

YAML采用块状风格和流动风格.在块样式中,缩进确定文档的结构.以下文档使用块样式.

root:
··key: value
Run Code Online (Sandbox Code Playgroud)

验证

在流式样中,特殊字符表示文档的结构.以下等效文档使用流式.

{
? root: {
? ? key: value
? }
}
Run Code Online (Sandbox Code Playgroud)

验证

您甚至可以在流动样式中混合缩进.

{
? root: {
··? key: value
····}
}
Run Code Online (Sandbox Code Playgroud)

验证

如果您正在混合块和流样式,则整个流样式部分必须遵循块样式缩进.

root:
··{
····key: value
··}
Run Code Online (Sandbox Code Playgroud)

验证

但是你仍然可以在流式样部分中混合缩进.

root:
··{
··? key: value
··}
Run Code Online (Sandbox Code Playgroud)

验证

如果您有一个单值文档,则可以使用各种空格来包围该值.

? ··value··? 
Run Code Online (Sandbox Code Playgroud)

验证

关键是,每个被解析为YAML的JSON文档都会将文档放入支持制表符的流式样式(因为初始{[字符),除非它是单值JSON文档,在这种情况下,YAML仍允许使用空格填充.

如果YAML解析器因JSON文档中的选项卡而抛出,则它不是有效的解析器.

话虽如此,您的示例失败,因为如果块样式映射值与映射名称不在同一行,则必须始终缩进.

root: {
··key: value
}
Run Code Online (Sandbox Code Playgroud)

无效的,但是

root:
··{
····key: value
··}
Run Code Online (Sandbox Code Playgroud)

有效的,并且

root: { key: value }
Run Code Online (Sandbox Code Playgroud)

有效.