J'ai donc deux fichiers YAML, "A" et "B" et je veux que le contenu de A soit inséré à l'intérieur de B, soit épissé dans la structure de données existante, comme un tableau, ou comme enfant d'un élément, comme la valeur pour une certaine clé de hachage.
Est-ce possible? Comment? Sinon, des indications sur une référence normative?
Réponses:
Non, YAML n'inclut aucun type de déclaration "import" ou "include".
la source
Votre question ne demande pas de solution Python, mais en voici une qui utilise PyYAML .
PyYAML vous permet d'attacher des constructeurs personnalisés (tels que
!include
) au chargeur YAML. J'ai inclus un répertoire racine qui peut être défini pour que cette solution prenne en charge les références de fichiers relatives et absolues.Solution basée sur la classe
Voici une solution basée sur les classes, qui évite la variable racine globale de ma réponse d'origine.
Voir cet essentiel pour une solution Python 3 similaire et plus robuste qui utilise une métaclasse pour enregistrer le constructeur personnalisé.
Un exemple:
foo.yaml
bar.yaml
Maintenant, les fichiers peuvent être chargés en utilisant:
la source
include
fonction peut être simplifié: `def include (loader, node):" "" Inclure un autre fichier YAML. "" "Filename = loader.construct_scalar (node) data = yaml.load (open (filename))`a: bla
bar.yaml: `! Include foo.yaml b: blubb` Pour que le résultat soit:` {{a ': bla,' b ': blubb}Si vous utilisez la version Symfony de YAML , c'est possible, comme ceci:
la source
Les inclusions ne sont pas directement prises en charge dans YAML pour autant que je sache, vous devrez fournir un mécanisme vous-même cependant, cela est généralement facile à faire.
J'ai utilisé YAML comme langage de configuration dans mes applications python, et dans ce cas, je définis souvent une convention comme celle-ci:
Ensuite, dans mon code (python), je fais:
Le seul inconvénient est que les variables dans les inclus prévaudront toujours sur les variables dans main, et il n'y a aucun moyen de modifier cette priorité en changeant l'endroit où l'instruction "includes: apparaît dans le fichier main.yml.
Sur un point légèrement différent, YAML ne prend pas en charge les inclusions car elles ne sont pas vraiment conçues de manière aussi exclusive qu'une annotation basée sur un fichier. Que signifierait une inclusion si vous l'avez obtenue en réponse à une demande AJAX?
la source
Pour les utilisateurs de Python, vous pouvez essayer pyyaml-include .
Installer
Usage
Considérez que nous avons de tels fichiers YAML :
1.yaml
contenu:2.yaml
contenu:Inclure les fichiers par nom
Au niveau supérieur:
Si
0.yaml
était:Nous aurons:
En cartographie:
Si
0.yaml
était:Nous aurons:
En séquence:
Si
0.yaml
était:Nous aurons:
Inclure des fichiers par caractères génériques
Le nom de fichier peut contenir des caractères génériques de style shell. Les données chargées à partir des fichiers trouvés par les caractères génériques seront définies dans une séquence.
Si
0.yaml
était:Nous aurons:
Afin d'activer l'
recursive
argument, nous écrirons la!include
balise en modeMapping
ouSequence
:Sequence
mode:Mapping
mode:la source
En développant la réponse de @ Josh_Bode, voici ma propre solution PyYAML, qui a l'avantage d'être une sous-classe autonome de
yaml.Loader
. Cela ne dépend d'aucuns globaux au niveau du module, ni de la modification de l'état global duyaml
module.la source
yaml.load(f, IncludeLoader)
intérieur,_include
vous pouvez éviter d'avoir à remplacer la racine. De plus, à moins que vous ne le fassiez, la solution ne fonctionnera pas sur plus d'un niveau, car les données incluses utilisent layaml.Loader
classe régulière .root
dekwargs
after settingself.root
pour le faire fonctionner avec des chaînes. J'ai déplacé le bloc if-else au-dessus de l'super
appel. Peut-être que quelqu'un d'autre peut confirmer ma découverte ou me montrer comment utiliser la classe avec des chaînes et leroot
paramètre.Je fais quelques exemples pour votre référence.
production
Update 2
et vous pouvez le combiner comme ça
la source
Malheureusement, YAML ne fournit pas cela dans sa norme.
Mais si vous utilisez Ruby, il y a une gemme fournissant la fonctionnalité que vous demandez en étendant la bibliothèque YAML ruby: https://github.com/entwanderer/yaml_extend
la source
Je pense que la solution utilisée par @ maxy-B est superbe. Cependant, cela n'a pas réussi pour moi avec des inclusions imbriquées. Par exemple, si config_1.yaml inclut config_2.yaml, qui inclut config_3.yaml, il y a eu un problème avec le chargeur. Cependant, si vous pointez simplement la nouvelle classe de chargeur sur elle-même, cela fonctionne! Plus précisément, si nous remplaçons l'ancienne fonction _include par la version très légèrement modifiée:
Après réflexion, je suis d'accord avec les autres commentaires, que le chargement imbriqué n'est pas approprié pour yaml en général car le flux d'entrée peut ne pas être un fichier, mais il est très utile!
la source
La norme YML ne spécifie pas de manière de procéder. Et ce problème ne se limite pas à YML. JSON a les mêmes limitations.
De nombreuses applications qui utilisent des configurations basées sur YML ou JSON rencontrent éventuellement ce problème. Et lorsque cela se produit, ils établissent leur propre convention .
par exemple pour les définitions d'API swagger:
par exemple pour les configurations de composition de docker:
Alternativement, si vous souhaitez diviser le contenu d'un fichier yml en plusieurs fichiers, comme une arborescence de contenu, vous pouvez définir votre propre convention de structure de dossiers et utiliser un script de fusion (existant).
la source
Peut-être que cela pourrait vous inspirer, essayez de vous aligner sur les conventions 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
la source
La norme YAML 1.2 n'inclut pas nativement cette fonctionnalité. Néanmoins, de nombreuses implémentations fournissent une extension pour ce faire.
Je présente un moyen d'y parvenir avec Java et
snakeyaml:1.24
(bibliothèque Java pour analyser / émettre des fichiers YAML) qui permet de créer une balise YAML personnalisée pour atteindre l'objectif suivant (vous verrez que je l'utilise pour charger des suites de tests définies dans plusieurs fichiers YAML et que je l'ai fait fonctionner comme une liste d'inclusions pour untest:
nœud cible ):Voici le Java à une classe qui permet de traiter la
!include
balise. Les fichiers sont chargés depuis classpath (répertoire des ressources Maven):la source
Avec Yglu , vous pouvez importer d'autres fichiers comme celui-ci:
A.yaml
B.yaml
Comme
$import
c'est une fonction, vous pouvez également passer une expression comme argument:Cela donnerait la même sortie que ci-dessus.
Avertissement: je suis l'auteur d'Yglu.
la source
Avec Symfony , sa gestion de yaml vous permettra indirectement d'imbriquer des fichiers yaml. L'astuce consiste à utiliser l'
parameters
option. par exemple:common.yml
config.yml
Le résultat sera le même que:
la source
Il n'était probablement pas pris en charge lorsque la question a été posée, mais vous pouvez importer un autre fichier YAML dans un:
Bien que je n'ai pas de référence en ligne, cela fonctionne pour moi.
la source
imports
.