YAML自定义标签与节点类型(Kind)相关规范及实现疑问
先跟大家明确下YAML规范里关于标签的基础要求:YAML标签是用来给每个节点附加元信息的,其中核心一条是每个标签必须指定预期的节点类型(kind),类型分为标量(scalar)、序列(sequence)、映射(mapping)三种。另外标量标签还得提供把格式化内容转成标准形式的机制,用来支持相等性校验;标签也可以附带额外信息,比如允许的内容值范围、标签解析逻辑之类的,所有该标签的节点都能复用这些信息。
基于这些规则,我有三个关于标签灵活性和类型关系的疑问:
疑问1:“预期类型”是不是只能指定一种?
换句话说,能不能实现一个标签,同时接受并预期映射和序列两种类型?比如下面这两种写法都能被正常解析:
this is a: !!very-kind-tag [1,2,3]
以及:
!!very-kind-tag one: 1 two: 2 three: 3
我翻了规范没看到明确的限制,想知道这种实现是否可行,要是不行的话原因是什么?
疑问2:解析后的节点类型能不能和原“预期类型”不一样?
举个例子:解析器读到的是标量类型的!!fullname Joe Smith,经过这个自定义标签的逻辑处理后,最终返回(或者说被视为)一个映射类型的结果{first name: Joe, last name: Smith},这种操作是否符合规范?
疑问3:“预期标量类型”是否等同于“预期字符串”?
具体来说:YAML里没显式打标签的节点,会被当作字符串处理,应用所有字符串相关的语法(比如折叠、多行格式之类的)。那“标量类型”本身(不是特指!!str标签)的表现是否和字符串完全一致?
比如Name: "Michael"、Name: Michael、Name: !!str Michael这几种写法基本没差,但我能不能定义一个自定义标签,它预期的是标量类型,但解析字符的逻辑和常规字符串不一样?比如自定义!!wow标签,让Name: !!wow "Michael"保留原始的字符(包括引号),而不是像常规字符串那样去掉引号再解析?
另外我看官方的!!binary标签示例里,用了和字符串标签一样的|字符,想知道这是不是标量标签必须遵循的?如果上面说的自定义解析是允许的,哪里能找到相关的说明文档?
额外问题:主流开源库的实际实现情况
如果YAML规范确实允许标签在类型上有这种灵活性,那现在主流的开源YAML库(比如PyYAML、SnakeYAML这些)实际是怎么实现的?有没有支持这类灵活的标签定义?
备注:内容来源于stack exchange,提问作者Cocktail




