所以,我知道我可以做这样的事情:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
并且有
sitelist
和 anotherlist
都包含 www.foo.com
和 www.bar.com
。然而,我真正想要的是 anotherlist
也包含 www.baz.com
,而不必重复 www.foo.com
和 www.baz.com
。这样做会在 YAML 解析器中给我一个语法错误:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
- www.baz.com
仅使用 anchor 和别名似乎不可能在不添加另一级子结构的情况下做我想做的事,例如:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
这意味着此 YAML 文件的使用者必须意识到这一点。
有没有纯粹的 YAML 方式来做这样的事情?或者我是否必须使用一些后 YAML 处理,例如实现变量替换或自动提升某些类型的子结构?我已经在做这种后处理来处理其他几个用例,所以我并不完全反对它。但是我的 YAML 文件将由人工编写,而不是机器生成,因此我希望在标准 YAML 语法基础上尽量减少用户需要记住的规则数量。
我也希望能够用 map 做类似的事情:
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
我已经搜索过 YAML spec ,但没有找到任何东西,所以我怀疑答案只是“不,你不能这样做”。但如果有人有任何想法,那就太好了。
编辑: 由于没有答案,我假设没有人发现我在 YAML 规范中没有发现的任何内容,并且这不能在 YAML 层完成。所以我提出了这个问题,以便对 YAML 进行后处理以帮助解决这个问题,以防将来有人发现这个问题。
最佳答案
The merge key type 可能就是你想要的。它使用特殊的 <<
映射键来指示合并,允许映射的别名(或此类别名的序列)用作初始化程序以合并为单个映射。此外,您仍然可以显式覆盖值,或添加更多不存在于合并列表中的值。
重要的是要注意它适用于映射,而不是作为第一个示例的序列。当您考虑它时,这是有道理的,并且您的示例看起来可能无论如何都不需要是连续的。只需将序列值更改为映射键就可以解决问题,如下面(未经测试的)示例所示:
sitelist: &sites
? www.foo.com # "www.foo.com" is the key, the value is null
? www.bar.com
anotherlist:
<< : *sites # merge *sites into this mapping
? www.baz.com # add extra stuff
需要注意的一些事情。首先,由于
<<
是一个键,所以每个节点只能指定一次。其次,当使用序列作为值时,顺序很重要。这在此处的示例中无关紧要,因为没有关联的值,但值得注意。关于arrays - 是否有用于共享列表或 map 的一部分的 YAML 语法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9254178/