Как я могу включить файл YAML в другой?

Итак, у меня есть два файла YAML, «A» и «B», и я хочу, чтобы содержимое A было вставлено внутрь B, либо врезано в существующую структуру данных, например массив, либо как дочерний элемент элемента, например значение для определенного хеш-ключа.

Это вообще возможно? Как? Если нет, то какие ссылки на нормативную ссылку?


person kch    schedule 09.02.2009    source источник
comment
therightstuff.de/2010/01/30/   -  person Darragh    schedule 20.10.2010
comment
Недавно я наткнулся на HiYaPyCo для Python, который делает именно это. Вы можете объединять разные файлы YAML вместе. Is - очень хороший модуль Python, который стоит знать.   -  person nowox    schedule 23.11.2015
comment
См. также: stackoverflow.com/questions/ 41620674 / use-placeholder-in-yaml   -  person dreftymac    schedule 02.10.2018


Ответы (15)


Нет, YAML не содержит каких-либо инструкций «import» или «include».

person jameshfisher    schedule 15.03.2013
comment
Вы можете создать обработчик! Include ‹filename›. - person clarkevans; 20.03.2014
comment
@clarkevans уверен, но эта конструкция будет вне языка YAML. - person jameshfisher; 20.03.2014
comment
Теперь это возможно. Я добавил ответ ниже ... надеюсь, это поможет. - person daveaspinall; 19.08.2015
comment
Если вы используете Rails, вы можете вставить ‹% = 'fdsa fdsa'%› синтаксис ERB, и он будет работать - person gleenn; 28.10.2016
comment
Я думаю, что этот ответ следует перефразировать как Нет, стандартный YAML не включает эту функцию. Тем не менее, многие реализации предоставляют для этого некоторые расширения. - person Franklin Yu; 12.09.2018
comment
импорт: # Общие параметры по умолчанию и выбор страны - {resource: parameters.yml - person Gustavo Maimone; 15.05.2020
comment
@daveaspinall Вводит в заблуждение. - person ruohola; 12.05.2021
comment
@ruohola Спасибо за полезный комментарий, ответ, которому 8 лет, и мой комментарий, которому 6 лет. - person daveaspinall; 12.05.2021
comment
@ruohola Я думаю, вам нужно перечитать комментарии ниже относительно того, что на самом деле было задано OP, и избегать размещения бесполезных негативных комментариев. Это не вводит в заблуждение, и 37 положительных отзывов (хотя и не в верхней части ответа) говорят, что некоторые люди сочли это ценным. - person daveaspinall; 12.05.2021

Ваш вопрос не требует решения Python, но здесь используется PyYAML.

PyYAML позволяет прикреплять пользовательские конструкторы (например, !include) к загрузчику YAML. Я включил корневой каталог, который можно настроить так, чтобы это решение поддерживало относительные и абсолютные ссылки на файлы.

Решение на основе классов

Вот решение на основе классов, которое позволяет избежать глобальной корневой переменной моего исходного ответа.

См. Этот gist для аналогичного, более надежного решения Python 3, которое использует метакласс для регистрации настраиваемого конструктора. .

import yaml
import os

class Loader(yaml.SafeLoader):

    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]]}
person Josh Bode    schedule 06.03.2012
comment
Это интересная функция, спасибо. Но какова цель всех этих манипуляций с root / old_root? Я полагаю, что код функции include можно упростить: `def include (loader, node): Включить другой файл YAML. filename = loader.construct_scalar (узел) data = yaml.load (open (имя файла)) ` - person Aliaksei Ramanau; 27.04.2012
comment
Корневой глобальный существует, поэтому относительный включает работу на любой глубине, например когда включаемые файлы, находящиеся в другом каталоге, включают файл, относящийся к этому каталогу. Absolute includes тоже должен работать. Вероятно, есть более чистый способ сделать это без глобальной переменной, возможно, используя собственный класс yaml.Loader. - person Josh Bode; 28.04.2012
comment
Возможно ли также иметь что-то вроде этого: foo.yaml: a: bla bar.yaml: `! Include foo.yaml b: blubb` Чтобы результат был:` {'a': bla, 'b': blubb} - person Martin; 03.08.2012
comment
@martin Я думаю, что, вероятно, будет трудно добиться, не вмешиваясь в класс Parser и / или Reader, чтобы эффективно внедрить включенный файл в поток токенов. Это точно не будет работать так, как я сделал это выше. - person Josh Bode; 14.08.2012
comment
Это должен быть принятый ответ. Кроме того, из соображений безопасности вы должны использовать yaml.safeload вместо yaml.load, чтобы специально созданный yaml не стал владельцем вашего сервиса. - person danielpops; 06.03.2018
comment
@danielpops хороший момент - однако я не видел способа заставить yaml.safe_load использовать собственный загрузчик - person Josh Bode; 07.03.2018
comment
comment
Спасибо @danielpops - обновлено выше и в указанной сущности - person Josh Bode; 08.03.2018
comment
Извините за беспокойство, ребята, но вы можете узнать, возможно ли импортировать только определенные данные из второго файла? Примерно так: foo.yaml c:! Include {list [1, 2, 3] from bar.yaml} - person WyllianNeo; 15.09.2020
comment
Я создаю новый вопрос (на основе этого) о моем комментарии выше, если кто-то хочет отказаться от правильной страницы - person WyllianNeo; 15.09.2020
comment
у меня не работает. в моем файле yaml есть #include shared.yaml. Я пробовал вышеуказанное решение, но все еще не обнаружил ошибку неопределенного псевдонима. Я меняю! Include - ›#include, все та же проблема. не понял, где используется загрузчик классов? - person imankalyan; 08.07.2021
comment
@imankalyan - пожалуйста, дайте ссылку на суть или аналогичный с минимальным рабочим примером, демонстрирующим вашу проблему. примечание: #include - это просто комментарий в YAML - вам обязательно нужно использовать форму !include - person Josh Bode; 09.07.2021

Насколько мне известно, включения напрямую не поддерживаются в YAML, вам придется предоставить механизм самостоятельно, однако, как правило, это легко сделать.

Я использовал YAML в качестве языка конфигурации в своих приложениях на Python, и в этом случае часто определяю такое соглашение:

>>> 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)))

Единственным недостатком является то, что переменные в include всегда будут переопределять переменные в main, и нет никакого способа изменить этот приоритет, изменив место, где в файле main.yml появляется оператор "includes:".

С другой стороны, YAML не поддерживает include, поскольку на самом деле он не разработан так же исключительно, как разметка на основе файлов. Что будет означать включение, если вы получили его в ответ на запрос AJAX?

person clh    schedule 23.01.2012
comment
это работает, только если файл yaml не содержит вложенной конфигурации. - person Freedom; 27.04.2018

Пользователи Python могут попробовать pyyaml-include.

Установить

pip install pyyaml-include

использование

import yaml
from yamlinclude import YamlIncludeConstructor

YamlIncludeConstructor.add_to_loader_class(loader_class=yaml.FullLoader, base_dir='/your/conf/dir')

with open('0.yaml') as f:
    data = yaml.load(f, Loader=yaml.FullLoader)

print(data)

Допустим, у нас есть такие файлы YAML:

├── 0.yaml
└── include.d
    ├── 1.yaml
    └── 2.yaml
  • Содержание 1.yaml:
name: "1"
  • Содержание 2.yaml:
name: "2"

Включать файлы по имени

  • На верхнем уровне:

    Если 0.yaml был:

!include include.d/1.yaml

Получим:

{"name": "1"}
  • В отображении:

    Если 0.yaml был:

file1: !include include.d/1.yaml
file2: !include include.d/2.yaml

Получим:

  file1:
    name: "1"
  file2:
    name: "2"
  • В последовательности:

    Если 0.yaml был:

files:
  - !include include.d/1.yaml
  - !include include.d/2.yaml

Получим:

files:
  - name: "1"
  - name: "2"

Примечание:

Имя файла может быть абсолютным (например, /usr/conf/1.5/Make.yml) или относительным (например, ../../cfg/img.yml).

Включать файлы с помощью подстановочных знаков

Имя файла может содержать подстановочные знаки в стиле оболочки. Данные, загруженные из файла (ов), найденного с помощью подстановочных знаков, будут установлены в последовательности.

Если 0.yaml был:

files: !include include.d/*.yaml

Получим:

files:
  - name: "1"
  - name: "2"

Примечание:

  • Для Python>=3.5, если recursive аргумент тега !include YAML равен true, шаблон “**” будет соответствовать любым файлам и ноль или более каталогов и подкаталоги.
  • Использование шаблона “**” в больших деревьях каталогов может занять чрезмерно много времени из-за рекурсивного поиска.

Чтобы включить аргумент recursive, мы напишем тег !include в режиме Mapping или Sequence:

  • Аргументы в режиме Sequence:
!include [tests/data/include.d/**/*.yaml, true]
  • Аргументы в Mapping режиме:
!include {pathname: tests/data/include.d/**/*.yaml, recursive: true}
person xqliang    schedule 02.04.2019
comment
На самом деле это не отвечает на вопрос. Это относится к решению Python, а не к решению, использующему стандартизированный формат YAML. - person oligofren; 19.06.2019
comment
@oligofren Пользовательские обработчики тегов - это функция YAML, позволяющая синтаксическим анализаторам расширять YAML для определения типов и реализации подобного настраиваемого поведения. Сама спецификация YAML была бы долгим шагом, чтобы предписать, как включение файлов должно работать со всеми разрозненными спецификациями путей ОС, файловыми системами и т. Д. - person Anton Strogonoff; 02.12.2019
comment
@AntonStrogonoff Спасибо, что обратил на это мое внимание. Не могли бы вы указать мне на такое место в RFC? В нем нет упоминания слова обычай. Ссылка yaml.org/spec/1.2/spec.html - person oligofren; 03.12.2019
comment
@oligofren Пожалуйста. Ищите «специфичные для приложения» теги. - person Anton Strogonoff; 03.12.2019

Расширяя ответ @Josh_Bode, вот мое собственное решение PyYAML, которое имеет то преимущество, что является автономным подклассом yaml.Loader. Это не зависит от каких-либо глобальных переменных уровня модуля или от изменения глобального состояния модуля 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                                                      
person Maxy-B    schedule 03.09.2012
comment
Наконец дошло до того, чтобы добавить к моему ответу подход, основанный на классах, но вы меня опередили :) Примечание: если вы используете yaml.load(f, IncludeLoader) внутри _include, вы можете избежать замены корня. Кроме того, если вы этого не сделаете, решение не будет работать более чем на один уровень, поскольку включенные данные используют обычный класс yaml.Loader. - person Josh Bode; 07.11.2012
comment
Мне пришлось удалить ключевое слово root из kwargs после установки self.root, чтобы заставить его работать со строками. Я переместил блок if-else над вызовом super. Может быть, кто-нибудь еще сможет подтвердить мой вывод или показать мне, как использовать класс со строками и параметром root. - person Woltan; 15.08.2016
comment
К сожалению, это не работает со ссылками, такими как `` Включено: & ВКЛЮЧЕНО! - person antony; 26.08.2016

Стандарт YML не определяет способ сделать это. И эта проблема не ограничивается YML. JSON имеет те же ограничения.

Многие приложения, использующие конфигурации на основе YML или JSON, рано или поздно сталкиваются с этой проблемой. И когда это происходит, они составляют свое собственное соглашение.

например для определений API чванства:

$ref: 'file.yml'

например для конфигураций docker compose:

services:
  app:
    extends:
      file: docker-compose.base.yml

В качестве альтернативы, если вы хотите разделить содержимое файла yml на несколько файлов, например дерево содержимого, вы можете определить собственное соглашение о структуре папок и использовать (существующий) сценарий слияния.

person bvdb    schedule 24.10.2019

Приведу несколько примеров для справки.

import yaml

main_yaml = """
Package:
 - !include _shape_yaml    
 - !include _path_yaml
"""

_shape_yaml = """
# Define
Rectangle: &id_Rectangle
    name: Rectangle
    width: &Rectangle_width 20
    height: &Rectangle_height 10
    area: !product [*Rectangle_width, *Rectangle_height]

Circle: &id_Circle
    name: Circle
    radius: &Circle_radius 5
    area: !product [*Circle_radius, *Circle_radius, pi]

# Setting
Shape:
    property: *id_Rectangle
    color: red
"""

_path_yaml = """
# Define
Root: &BASE /path/src/

Paths: 
    a: &id_path_a !join [*BASE, a]
    b: &id_path_b !join [*BASE, b]

# Setting
Path:
    input_file: *id_path_a
"""


# define custom tag handler
def yaml_import(loader, node):
    other_yaml_file = loader.construct_scalar(node)
    return yaml.load(eval(other_yaml_file), Loader=yaml.SafeLoader)


def yaml_product(loader, node):
    import math
    list_data = loader.construct_sequence(node)
    result = 1
    pi = math.pi
    for val in list_data:
        result *= eval(val) if isinstance(val, str) else val
    return result


def yaml_join(loader, node):
    seq = loader.construct_sequence(node)
    return ''.join([str(i) for i in seq])


def yaml_ref(loader, node):
    ref = loader.construct_sequence(node)
    return ref[0]


def yaml_dict_ref(loader: yaml.loader.SafeLoader, node):
    dict_data, key, const_value = loader.construct_sequence(node)
    return dict_data[key] + str(const_value)


def main():
    # register the tag handler
    yaml.SafeLoader.add_constructor(tag='!include', constructor=yaml_import)
    yaml.SafeLoader.add_constructor(tag='!product', constructor=yaml_product)
    yaml.SafeLoader.add_constructor(tag='!join', constructor=yaml_join)
    yaml.SafeLoader.add_constructor(tag='!ref', constructor=yaml_ref)
    yaml.SafeLoader.add_constructor(tag='!dict_ref', constructor=yaml_dict_ref)

    config = yaml.load(main_yaml, Loader=yaml.SafeLoader)

    pk_shape, pk_path = config['Package']
    pk_shape, pk_path = pk_shape['Shape'], pk_path['Path']
    print(f"shape name: {pk_shape['property']['name']}")
    print(f"shape area: {pk_shape['property']['area']}")
    print(f"shape color: {pk_shape['color']}")

    print(f"input file: {pk_path['input_file']}")


if __name__ == '__main__':
    main()

выход

shape name: Rectangle
shape area: 200
shape color: red
input file: /path/src/a

Обновление 2

и вы можете комбинировать это, вот так

# xxx.yaml
CREATE_FONT_PICTURE:
  PROJECTS:
    SUNG: &id_SUNG
      name: SUNG
      work_dir: SUNG
      output_dir: temp
      font_pixel: 24


  DEFINE: &id_define !ref [*id_SUNG]  # you can use config['CREATE_FONT_PICTURE']['DEFINE'][name, work_dir, ... font_pixel]
  AUTO_INIT:
    basename_suffix: !dict_ref [*id_define, name, !product [5, 3, 2]]  # SUNG30

# ↓ This is not correct.
# basename_suffix: !dict_ref [*id_define, name, !product [5, 3, 2]]  # It will build by Deep-level. id_define is Deep-level: 2. So you must put it after 2. otherwise, it can't refer to the correct value.
person Carson    schedule 22.11.2019

С помощью Yglu вы можете импортировать другие файлы, например:

А.ямл

foo: !? $import('B.yaml')

Б.ямл

bar: Hello
$ yglu A.yaml
foo:
  bar: Hello

Поскольку $import - это функция, вы также можете передать выражение в качестве аргумента:

  dep: !- b
  foo: !? $import($_.dep.toUpper() + '.yaml')

Это даст тот же результат, что и выше.

Отказ от ответственности: я являюсь автором Yglu.

person lbovet    schedule 18.02.2020

К сожалению, YAML не предоставляет этого в своем стандарте.

Но если вы используете Ruby, есть драгоценный камень, обеспечивающий запрашиваемую вами функциональность путем расширения библиотеки ruby ​​YAML: https://github.com/entwanderer/yaml_extend

person user8419486    schedule 04.08.2017

Стандартный YAML 1.2 изначально не включает эту функцию. Тем не менее, многие реализации предоставляют для этого некоторые расширения.

Я представляю способ достижения этого с помощью Java и snakeyaml:1.24 (библиотека Java для синтаксического анализа / выдачи файлов YAML), который позволяет создать собственный тег YAML для достижения следующей цели (вы увидите, что я использую его для загрузки наборов тестов, определенных в нескольких YAML. файлы и что я заставил его работать как список включаемых для целевого узла test:):

# ... yaml prev stuff

tests: !include
  - '1.hello-test-suite.yaml'
  - '3.foo-test-suite.yaml'
  - '2.bar-test-suite.yaml'

# ... more yaml document

Вот одноклассная Java, позволяющая обрабатывать тег !include. Файлы загружаются из пути к классам (каталог ресурсов Maven):

/**
 * Custom YAML loader. It adds support to the custom !include tag which allows splitting a YAML file across several
 * files for a better organization of YAML tests.
 */
@Slf4j   // <-- This is a Lombok annotation to auto-generate logger
public class MyYamlLoader {

    private static final Constructor CUSTOM_CONSTRUCTOR = new MyYamlConstructor();

    private MyYamlLoader() {
    }

    /**
     * Parse the only YAML document in a stream and produce the Java Map. It provides support for the custom !include
     * YAML tag to split YAML contents across several files.
     */
    public static Map<String, Object> load(InputStream inputStream) {
        return new Yaml(CUSTOM_CONSTRUCTOR)
                .load(inputStream);
    }


    /**
     * Custom SnakeYAML constructor that registers custom tags.
     */
    private static class MyYamlConstructor extends Constructor {

        private static final String TAG_INCLUDE = "!include";

        MyYamlConstructor() {
            // Register custom tags
            yamlConstructors.put(new Tag(TAG_INCLUDE), new IncludeConstruct());
        }

        /**
         * The actual include tag construct.
         */
        private static class IncludeConstruct implements Construct {

            @Override
            public Object construct(Node node) {
                List<Node> inclusions = castToSequenceNode(node);
                return parseInclusions(inclusions);
            }

            @Override
            public void construct2ndStep(Node node, Object object) {
                // do nothing
            }

            private List<Node> castToSequenceNode(Node node) {
                try {
                    return ((SequenceNode) node).getValue();

                } catch (ClassCastException e) {
                    throw new IllegalArgumentException(String.format("The !import value must be a sequence node, but " +
                            "'%s' found.", node));
                }
            }

            private Object parseInclusions(List<Node> inclusions) {

                List<InputStream> inputStreams = inputStreams(inclusions);

                try (final SequenceInputStream sequencedInputStream =
                             new SequenceInputStream(Collections.enumeration(inputStreams))) {

                    return new Yaml(CUSTOM_CONSTRUCTOR)
                            .load(sequencedInputStream);

                } catch (IOException e) {
                    log.error("Error closing the stream.", e);
                    return null;
                }
            }

            private List<InputStream> inputStreams(List<Node> scalarNodes) {
                return scalarNodes.stream()
                        .map(this::inputStream)
                        .collect(toList());
            }

            private InputStream inputStream(Node scalarNode) {
                String filePath = castToScalarNode(scalarNode).getValue();
                final InputStream is = getClass().getClassLoader().getResourceAsStream(filePath);
                Assert.notNull(is, String.format("Resource file %s not found.", filePath));
                return is;
            }

            private ScalarNode castToScalarNode(Node scalarNode) {
                try {
                    return ((ScalarNode) scalarNode);

                } catch (ClassCastException e) {
                    throw new IllegalArgumentException(String.format("The value must be a scalar node, but '%s' found" +
                            ".", scalarNode));
                }
            }
        }

    }

}
person Gerard Bosch    schedule 29.07.2019

Я думаю, что решение, используемое @ maxy-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 в целом, поскольку входной поток может не быть файлом, но это очень полезно!

person PaddyM    schedule 26.02.2018

Может быть, это может вас вдохновить, попробуйте соответствовать соглашениям jbb:

https://docs.openstack.org/infra/jenkins-job-builder/definition.html#inclusion-tags.

- job: name: test-job-include-raw-1 builders: - shell: !include-raw: include-raw001-hello-world.sh

person RzR    schedule 09.07.2018

Добавив первоначальный ответ @Joshbode выше, я немного изменил фрагмент, чтобы поддерживать шаблоны подстановочных знаков в стиле UNIX.

Однако я не тестировал в Windows. Я столкнулся с проблемой разделения массива в большом yaml на несколько файлов для упрощения обслуживания и искал решение для ссылки на несколько файлов в одном массиве базового yaml. Отсюда и решение ниже. Решение не поддерживает рекурсивную ссылку. Он поддерживает подстановочные знаки только на заданном уровне каталога, на который ссылается базовый yaml.

import yaml
import os
import glob


# Base code taken from below link :-
# Ref:https://stackoverflow.com/a/9577670
class Loader(yaml.SafeLoader):

    def __init__(self, stream):

        self._root = os.path.split(stream.name)[0]

        super(Loader, self).__init__(stream)

    def include(self, node):
        consolidated_result = None
        filename = os.path.join(self._root, self.construct_scalar(node))

        # Below section is modified for supporting UNIX wildcard patterns
        filenames = glob.glob(filename)
        
        # Just to ensure the order of files considered are predictable 
        # and easy to debug in case of errors.
        filenames.sort()
        for file in filenames:
            with open(file, 'r') as f:
                result = yaml.load(f, Loader)

            if isinstance(result, list):
                if not isinstance(consolidated_result, list):
                    consolidated_result = []
                consolidated_result += result
            elif isinstance(result, dict):
                if not isinstance(consolidated_result, dict):
                    consolidated_result = {}
                consolidated_result.update(result)
            else:
                consolidated_result = result

        return consolidated_result


Loader.add_constructor('!include', Loader.include)

Использование

a:
  !include a.yaml

b:
  # All yamls included within b folder level will be consolidated
  !include b/*.yaml

person ram    schedule 11.03.2021

В Symfony обработка yaml косвенно позволяет вам вкладывать файлы yaml. Уловка состоит в том, чтобы использовать параметр parameters. например:

common.yml

parameters:
    yaml_to_repeat:
        option: "value"
        foo:
            - "bar"
            - "baz"

config.yml

imports:
    - { resource: common.yml }
whatever:
    thing: "%yaml_to_repeat%"
    other_thing: "%yaml_to_repeat%"

Результат будет такой же, как:

whatever:
    thing:
        option: "value"
        foo:
            - "bar"
            - "baz"
    other_thing:
        option: "value"
        foo:
            - "bar"
            - "baz"
person jxmallett    schedule 12.02.2018

Вероятно, он не поддерживался, когда был задан вопрос, но вы можете импортировать другой файл YAML в один:

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

Хотя у меня нет онлайн-справочника, но это работает для меня.

person Sankalp    schedule 01.08.2014
comment
Это вообще не включает. Он создает сопоставление с последовательностью, состоящей из одной строки /your_location_to_yaml_file/Util.area.yaml в качестве значения для ключа imports. - person Anthon; 06.06.2015