Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在YAML中,带引号的标量必须由解析器解释为字符串吗?_Yaml_Snakeyaml - Fatal编程技术网

在YAML中,带引号的标量必须由解析器解释为字符串吗?

在YAML中,带引号的标量必须由解析器解释为字符串吗?,yaml,snakeyaml,Yaml,Snakeyaml,我在互联网上看到过这样的建议:如果希望将YAML标量值作为字符串处理,应该引用它: foo : "2018-04-17" 在上面的示例中,此建议旨在告诉我值2018-04-17将由任何给定的YAML解析器作为其母语的字符串类型进行处理。例如,如果这个建议是真的,我们会将其解释为java.lang.String,而不是java.util.Date。(碰巧,SnakeYAML将其解释为java.util.Date,是否引用,这就是我问这个问题的原因。) 但是,尽管这个建议可能碰巧适用于任何给定的解

我在互联网上看到过这样的建议:如果希望将YAML标量值作为字符串处理,应该引用它:

foo : "2018-04-17"
在上面的示例中,此建议旨在告诉我值
2018-04-17
将由任何给定的YAML解析器作为其母语的字符串类型进行处理。例如,如果这个建议是真的,我们会将其解释为
java.lang.String
,而不是
java.util.Date
。(碰巧,SnakeYAML将其解释为
java.util.Date
,是否引用,这就是我问这个问题的原因。)

但是,尽管这个建议可能碰巧适用于任何给定的解析器,但我看不出这个建议可能来自何方。我能找到的最接近的东西是:

YAML允许标量以多种格式显示。例如,整数“
11
”也可以写为“
0xB
”。标记必须指定一种机制,用于将格式化内容转换为规范形式,以便在平等性测试中使用。与节点样式一样,该格式是一种表示细节,不会反映在序列化树和表示图中

以及:

标量样式是一种表示细节,不能用于传递内容信息,但为了标记解析而区分普通标量的情况除外

以及:

注意,分辨率不能考虑诸如注释、缩进和节点样式等演示文稿细节。


然而,我看到很多YAML文档依赖于双引号-the-value-means-it-will-parsed-as-a-string建议,这让我觉得我误读了一些东西。在这个问题上有争议吗?

YAML 1.1规范的相关章节(注意,SnakeYaml是YAML 1.1,因此,1.2规范不一定适用):

不要求在字符流中显式指定完整表示的所有标记。在解析过程中,省略标记的节点将获得一个非特定的标记:“?”用于普通标量,而“!”用于所有其他节点。[……]

建议将具有“!”非特定标记的节点解析为“tag:yaml.org,2002:seq”、“tag:yaml.org,2002:map”或“tag:yaml.org,2002:str”,具体取决于节点的类型。此约定允许YAML字符流的作者对标记解析过程施加某种程度的控制。通过显式指定具有“!”非特定标记的纯标量,节点将解析为字符串,就像它是以块样式引用或写入的一样。但是,请注意,每个应用程序都可以覆盖此行为。例如,应用程序可能会自动检测源代码中使用的编程语言类型,将其表示为非纯标量,并相应地解析它

总之,YAML处理器不需要将引用的标量解析为字符串,YAML也不指定映射到哪个本机类型
tag:YAML.org,2002:str
。事实上,大多数YAML实现只遵循了部分建议。例如,如果使用SnakeYaml将YAML反序列化为POJO/JavaBean,通常不会在YAML中使用任何显式标记,但会将映射解析为根类结构中相应的Java类,而不是此建议所建议的泛型
Map
(因为所有没有显式标记的映射都会得到
非特定标记)

请注意,YAML 1.2中对此进行了更改:

在解析过程中,缺少显式标记的节点将被赋予一个非特定标记:“!”用于非普通标量,而“?”用于所有其他节点

这与大多数实现更接近,但例如,如果您反序列化到类
class Foo{String bar;}
,这仍然会加载,尽管
bar
不是字符串,而是字段名:

"bar": some value
因此,使用YAML的建议是在应用程序端指定所需的结构——在SnakeYaml中,您可以设置根类类型,然后每个值都将在层次结构中的某个点映射到所需的类型,只要它能够映射到该点,而不管它是带引号的还是不带引号的。一般来说,这更有意义让应用程序在整个层次结构中指定它期望的值,而不是YAML作者通过引用来指定

解析节点的标记必须仅取决于以下三个参数:(1)节点的非特定标记,(2)从根到节点的路径,以及(3)节点的内容(以及类型)

解析标记是用于确定目标类型的YAML术语。允许根据其在层次结构中的位置确定目标类型:根类型由元素是YAML文档的根这一事实确定,如果是SnakeYaml,则可以通过API输入。所有其他类型由它们是根类型的后代


最后一点注意:如果你真的想把某个东西变成字符串,
!!str 2018-04-17
就可以了,因为它为节点设置了一个特定的标记。

谢谢你。所以本质上就像我想的那样:未标记(标量)的YAML可以被解析器以多种不同的方式解析,而不管引用的样式如何。在这种情况下,我无法控制它(a) 源文档或(b)解析器,因此这将变得有趣。