我怎样才能包括在另一个YAML文件?

所以我有两个YAML文件,“A”和“B”,我希望将A的内容插入到B中,或者拼成现有的数据结构,如数组,或者作为元素的子元素对于某个散列键。

这可能吗? 怎么样? 如果没有,任何指向规范性参考的指针?

不,YAML不包含任何种类的“导入”或“包含”声明。

你的问题不要求Python解决scheme,但是这里是使用PyYAML的 。

PyYAML允许你将自定义构造函数(如!include )附加到YAML加载器。 我已经包含了一个可以设置的根目录,以便这个解决scheme支持相对和绝对文件引用。

基于类的解决scheme

这是一个基于类的解决scheme,它避免了原始响应的全局根variables。

请参阅此要点以获得类似的,更强大的使用元类注册自定义构造函数的Python 3解决scheme。

 import yaml import os.path class Loader(yaml.Loader): def __init__(self, stream): self._root = os.path.split(stream.name)[0] super(Loader, self).__init__(stream) def include(self, node): filename = os.path.join(self._root, self.construct_scalar(node)) with open(filename, 'r') as f: return yaml.load(f, Loader) Loader.add_constructor('!include', Loader.include) 

一个例子:

foo.yaml

 a: 1 b: - 1.43 - 543.55 c: !include bar.yaml 

bar.yaml

 - 3.6 - [1, 2, 3] 

现在可以使用以下方式加载文件:

 >>> with open('foo.yaml', 'r') as f: >>> data = yaml.load(f, Loader) >>> data {'a': 1, 'b': [1.43, 543.55], 'c': [3.6, [1, 2, 3]]} 

如果你使用Symfony的YAML版本 ,这是可能的,就像这样:

 imports: - { resource: sub-directory/file.yml } - { resource: sub-directory/another-file.yml } 

包括直接支持yaml据我所知,你将不得不提供一个机制,但是,这通常很容易做到。

我已经在我的Python应用程序中使用yaml作为configuration语言,在这种情况下,经常会像这样定义一个对话框:

 >>> main.yml <<< includes: [ wibble.yml, wobble.yml] 

然后在我的(python)代码中:

 import yaml cfg = yaml.load(open("main.yml")) for inc in cfg.get("includes", []): cfg.update(yaml.load(open(inc))) 

唯一的缺点是包含中的variables总是会覆盖main中的variables,并且无法通过更改main.yml文件中包含“include:语句”的位置来更改该优先级。

稍有不同的是,yaml不支持include,因为它不是真的被devise成仅仅作为基于文件的标记。 如果你在回应ajax请求时得到了什么,那么包含什么意思呢?

扩展@ Josh_Bode的答案,这里是我自己的PyYAML解决scheme,它的优点是作为yaml.Loader一个独立的子类。 它不依赖于任何模块级的全局variables,也不依赖于修改yaml模块的全局状态。

 import yaml, os class IncludeLoader(yaml.Loader): """ yaml.Loader subclass handles "!include path/to/foo.yml" directives in config files. When constructed with a file object, the root path for includes defaults to the directory containing the file, otherwise to the current working directory. In either case, the root path can be overridden by the `root` keyword argument. When an included file F contain its own !include directive, the path is relative to F's location. Example: YAML file /home/frodo/one-ring.yml: --- Name: The One Ring Specials: - resize-to-wearer Effects: - !include path/to/invisibility.yml YAML file /home/frodo/path/to/invisibility.yml: --- Name: invisibility Message: Suddenly you disappear! Loading: data = IncludeLoader(open('/home/frodo/one-ring.yml', 'r')).get_data() Result: {'Effects': [{'Message': 'Suddenly you disappear!', 'Name': 'invisibility'}], 'Name': 'The One Ring', 'Specials': ['resize-to-wearer']} """ def __init__(self, *args, **kwargs): super(IncludeLoader, self).__init__(*args, **kwargs) self.add_constructor('!include', self._include) if 'root' in kwargs: self.root = kwargs['root'] elif isinstance(self.stream, file): self.root = os.path.dirname(self.stream.name) else: self.root = os.path.curdir 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')) self.root = oldRoot return data 

不幸的是YAML没有提供这个标准。

但是,如果您使用的是Ruby,那么通过扩展Ruby YAML库,可以提供您所要求的function: https : //github.com/entwanderer/yaml_extend

在提出问题时可能不支持,但可以将其他YAML文件导入到其中:

 imports: [/your_location_to_yaml_file/Util.area.yaml] 

虽然我没有任何在线参考,但这对我很有用。

在这里,我用了mako

A.TXT

这是文件的顶部
<%include file ='b.txt'/>
这是文件a的底部

b.txt

这是文件b

test.py

 from mako.template import Template from mako.lookup import TemplateLookup import os directory = os.path.dirname( os.path.abspath( __file__ ) ) mylookup = TemplateLookup(directories=[directory]) mytemplate = Template(filename="a.txt", lookup=mylookup) finalsrc = mytemplate.render() # finalsrc can be treated as yaml or whatever you like 

$ python test.py
这是文件的顶部
这是文件b
这是文件a的底部