我有两个YAML文件,“A”和“B”,我希望将A的内容插入到B中,要么拼接到现有的数据结构中,就像数组一样,要么作为元素的子元素,就像某个散列键的值一样。
这可能吗?怎么做?如果不是,是否有指向规范引用的指针?
我有两个YAML文件,“A”和“B”,我希望将A的内容插入到B中,要么拼接到现有的数据结构中,就像数组一样,要么作为元素的子元素,就像某个散列键的值一样。
这可能吗?怎么做?如果不是,是否有指向规范引用的指针?
当前回答
不,标准YAML不包括任何类型的“import”或“include”语句。
其他回答
不幸的是,YAML在其标准中没有提供这个功能。
但是如果你正在使用Ruby,有一个gem通过扩展Ruby YAML库来提供你所要求的功能: https://github.com/entwanderer/yaml_extend
我认为@max - b使用的解决方案看起来很棒。但是,对于嵌套的包含,它没有成功。例如,如果config_1。Yaml包含config_2。Yaml,其中包括config_3。Yaml,装弹机有问题。但是,如果您在加载时简单地将新的加载器类指向它自己,它就可以工作!具体来说,如果我们将旧的_include函数替换为稍微修改过的版本:
def _include(self, loader, node):
oldRoot = self.root
filename = os.path.join(self.root, loader.construct_scalar(node))
self.root = os.path.dirname(filename)
data = yaml.load(open(filename, 'r'), loader = IncludeLoader)
self.root = oldRoot
return data
经过反思,我同意其他评论,嵌套加载一般不适合yaml,因为输入流可能不是一个文件,但它非常有用!
也许这可以激励你,试着与jbb惯例保持一致:
https://docs.openstack.org/infra/jenkins-job-builder/definition.html#inclusion-tags
-工作: 名称:test-job-include-raw-1 建造者: -壳: !包括生:include-raw001-hello-world.sh
根据之前的帖子:
class SimYamlLoader(yaml.SafeLoader):
'''
Simple custom yaml loader that supports include, e.g:
main.yaml:
- !include file1.yaml
- !include dir/file2.yaml
'''
def __init__(self, stream):
self.root = os.path.split(stream.name)[0]
super().__init__(stream)
def _include(loader, node):
filename = os.path.join(loader.root, loader.construct_scalar(node))
with open(filename, 'r') as f:
return yaml.load(f, SimYamlLoader)
SimYamlLoader.add_constructor('!include', _include)
# example:
with open('main.yaml', 'r') as f:
lists = yaml.load(f, SimYamlLoader)
# if you want to merge the lists
data = functools.reduce(
lambda x, y: x if y is None else {**x, **dict(y)}, lists, {})
# python 3.10+:lambda x, y: x if y is None else x | dict(y), lists, {})
不,标准YAML不包括任何类型的“import”或“include”语句。