所以,我知道我可以这样做:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
Run Code Online (Sandbox Code Playgroud)
并拥有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
Run Code Online (Sandbox Code Playgroud)
只使用锚和别名,似乎不可能做我想要的而不添加另一级子结构,例如:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
Run Code Online (Sandbox Code Playgroud)
这意味着此YAML文件的使用者必须了解它.
有一种纯粹的YAML方式做这样的事情吗?或者我是否必须使用一些后YAML处理,例如实现变量替换或自动提升某些类型的子结构?我已经在进行那种后处理来处理其他一些用例,所以我并不完全厌恶它.但我的YAML文件将由人类编写,而不是由机器生成,因此我希望尽量减少用户在标准YAML语法之上需要记忆的规则数量.
我也希望能够用地图做类似的事情:
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
Run Code Online (Sandbox Code Playgroud)
我有一个搜索YAML规范,但找不到任何东西,所以我怀疑答案只是"不,你不能这样做".但是,如果有人有任何想法会很棒.
编辑:由于没有答案,我假设没有人发现我在YAML规范中没有的任何东西,并且这不能在YAML层完成.所以我打开了一个问题,想要对YAML进行后处理以帮助解决这个问题,以防将来有人发现这个问题.
我想在YAML中合并数组,并通过ruby加载它们 -
some_stuff: &some_stuff
- a
- b
- c
combined_stuff:
<<: *some_stuff
- d
- e
- f
Run Code Online (Sandbox Code Playgroud)
我想将组合数组作为 [a,b,c,d,e,f]
我收到错误:在解析块映射时没有找到预期的键
如何在YAML中合并数组?
我想要一个基本配置文件,其他配置文件使用它来共享通用配置。
例如,如果我有一个base.yml文件
foo: 1
bar:
- 2
- 3
Run Code Online (Sandbox Code Playgroud)
然后是第二个some_file.yml文件
foo: 2
baz: "baz"
Run Code Online (Sandbox Code Playgroud)
我希望最终得到一个合并的配置文件
foo: 2
bar:
- 2
- 3
baz: "baz"
Run Code Online (Sandbox Code Playgroud)
编写处理标签的自定义加载器很容易!include。
class ConfigLoader(yaml.SafeLoader):
def __init__(self, stream):
super().__init__(stream)
self._base = Path(stream.name).parent
def include(self, node):
file_name = self.construct_scalar(node)
file_path = self._base.joinpath(file_name)
with file_path.open("rt") as fh:
return yaml.load(fh, IncludeLoader)
Run Code Online (Sandbox Code Playgroud)
然后我可以解析一个!include标签。所以如果我的文件是
inherit:
!include base.yml
foo: 2
baz: "baz"
Run Code Online (Sandbox Code Playgroud)
但现在基本配置是一个映射。即如果我加载文件我最终会得到
foo: 1
bar:
- 2
- 3
Run Code Online (Sandbox Code Playgroud)
但是如果我不将标签作为映射的一部分,例如
!include base.yml
foo: 2
baz: …Run Code Online (Sandbox Code Playgroud)