Ich habe also zwei YAML-Dateien, "A" und "B", und ich möchte, dass der Inhalt von A in B eingefügt wird, entweder wie ein Array in die vorhandene Datenstruktur oder als untergeordnetes Element eines Elements wie der Wert für einen bestimmten Hash-Schlüssel.
Ist das überhaupt möglich? Wie? Wenn nicht, Hinweise auf eine normative Referenz?
yaml
transclusion
kch
quelle
quelle
Antworten:
Nein, YAML enthält keine "import" - oder "include" -Anweisung.
quelle
Ihre Frage fragt nicht nach einer Python-Lösung, aber hier ist eine, die PyYAML verwendet .
Mit PyYAML können Sie benutzerdefinierte Konstruktoren (z. B.
!include
) an den YAML-Loader anhängen . Ich habe ein Stammverzeichnis eingefügt, das so eingestellt werden kann, dass diese Lösung relative und absolute Dateiverweise unterstützt.Klassenbasierte Lösung
Hier ist eine klassenbasierte Lösung, die die globale Stammvariable meiner ursprünglichen Antwort vermeidet.
In dieser Übersicht finden Sie eine ähnliche, robustere Python 3-Lösung, die eine Metaklasse zum Registrieren des benutzerdefinierten Konstruktors verwendet.
Ein Beispiel:
foo.yaml
bar.yaml
Jetzt können die Dateien geladen werden mit:
quelle
include
Funktionscode kann vereinfacht werden: `def include (Loader, Node):" "Include eine andere YAML-Datei." "Dateiname = loader.construct_scalar (Node) data = yaml.load (open (Dateiname))`a: bla
bar.yaml: `! Include foo.yaml b: blubb` Das Ergebnis wäre also:` {'a': bla, 'b': blubb}Wenn Sie die Symfony-Version von YAML verwenden , ist dies folgendermaßen möglich:
quelle
Includes werden meines Wissens nicht direkt in YAML unterstützt. Sie müssen selbst einen Mechanismus bereitstellen. Dies ist jedoch im Allgemeinen einfach.
Ich habe YAML als Konfigurationssprache in meinen Python-Apps verwendet und in diesem Fall häufig eine Konvention wie die folgende definiert:
Dann mache ich in meinem (Python-) Code:
Der einzige Nachteil ist, dass Variablen in den Includes immer die Variablen in main überschreiben, und es gibt keine Möglichkeit, diese Priorität zu ändern, indem Sie ändern, wo die Anweisung "include:" in der Datei main.yml angezeigt wird.
In einem etwas anderen Punkt unterstützt YAML Includes nicht, da es nicht so exklusiv wie ein dateibasiertes Markup konzipiert ist. Was würde ein Include bedeuten, wenn Sie es als Antwort auf eine AJAX-Anfrage erhalten würden?
quelle
Für Python-Benutzer können Sie pyyaml-include ausprobieren .
Installieren
Verwendung
Bedenken Sie, wir haben solche YAML- Dateien:
1.yaml
Inhalt:2.yaml
Inhalt:Dateien nach Namen einschließen
Auf der obersten Ebene:
Wenn
0.yaml
war:Wir werden .. bekommen:
Im Mapping:
Wenn
0.yaml
war:Wir werden .. bekommen:
Der Reihe nach:
Wenn
0.yaml
war:Wir werden .. bekommen:
Fügen Sie Dateien mit Platzhaltern hinzu
Der Dateiname kann Platzhalter im Shell-Stil enthalten. Daten, die aus den von Platzhaltern gefundenen Dateien geladen wurden, werden in einer Reihenfolge festgelegt.
Wenn
0.yaml
war:Wir werden .. bekommen:
Um das
recursive
Argument zu aktivieren , schreiben wir das!include
Tag inMapping
oderSequence
mode:Sequence
Modus:Mapping
Modus:quelle
Um die Antwort von @ Josh_Bode zu erweitern, hier ist meine eigene PyYAML-Lösung, die den Vorteil hat, eine in sich geschlossene Unterklasse von zu sein
yaml.Loader
. Dies hängt nicht von Globals auf Modulebene oder von der Änderung des globalen Status desyaml
Moduls ab.quelle
yaml.load(f, IncludeLoader)
innerhalb_include
Sie vermeiden können , mit der Wurzel zu ersetzen. Wenn Sie dies nicht tun, funktioniert die Lösung nicht mehr als eine Ebene tief, da die enthaltenen Daten die reguläreyaml.Loader
Klasse verwenden.root
vonkwargs
nach der Einstellung entfernenself.root
, damit es mit Zeichenfolgen funktioniert. Ich habe den if-else-Block über densuper
Anruf verschoben . Vielleicht kann jemand anderes meinen Befund bestätigen oder mir zeigen, wie man die Klasse mit Strings und demroot
Parameter verwendet.Ich mache einige Beispiele als Referenz.
Ausgabe
Update 2
und Sie können es so kombinieren
quelle
Leider bietet YAML dies nicht in seinem Standard an.
Wenn Sie jedoch Ruby verwenden, gibt es ein Juwel, das die von Ihnen gewünschte Funktionalität bietet, indem Sie die Ruby-YAML-Bibliothek erweitern: https://github.com/entwanderer/yaml_extend
quelle
Ich finde die von @ maxy-B verwendete Lösung großartig. Mit verschachtelten Einschlüssen gelang es mir jedoch nicht. Wenn config_1.yaml beispielsweise config_2.yaml enthält, einschließlich config_3.yaml, ist ein Problem mit dem Loader aufgetreten. Wenn Sie die neue Loader-Klasse jedoch beim Laden einfach auf sich selbst zeigen, funktioniert dies! Insbesondere, wenn wir die alte _include-Funktion durch die sehr leicht modifizierte Version ersetzen:
Nach Überlegung stimme ich den anderen Kommentaren zu, dass das verschachtelte Laden für yaml im Allgemeinen nicht geeignet ist, da der Eingabestream möglicherweise keine Datei ist, aber es ist sehr nützlich!
quelle
Der YML-Standard gibt keine Möglichkeit an, dies zu tun. Und dieses Problem beschränkt sich nicht auf YML. JSON hat die gleichen Einschränkungen.
Bei vielen Anwendungen, die YML- oder JSON-basierte Konfigurationen verwenden, tritt dieses Problem möglicherweise auf. Und wenn das passiert, bilden sie ihre eigene Konvention .
zB für Swagger-API-Definitionen:
zB für Docker komponieren Konfigurationen:
Wenn Sie den Inhalt einer XML-Datei wie einen Inhaltsbaum in mehrere Dateien aufteilen möchten, können Sie alternativ Ihre eigene Ordnerstrukturkonvention definieren und ein (vorhandenes) Zusammenführungsskript verwenden.
quelle
Vielleicht könnte dich das inspirieren, versuche dich an jbb-Konventionen auszurichten:
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
quelle
Standard YAML 1.2 enthält diese Funktion nicht nativ. Trotzdem bieten viele Implementierungen eine Erweiterung, um dies zu tun.
Ich präsentiere eine Möglichkeit, dies mit Java und
snakeyaml:1.24
(Java-Bibliothek zum Parsen / Ausgeben von YAML-Dateien) zu erreichen, mit der ein benutzerdefiniertes YAML-Tag erstellt werden kann, um das folgende Ziel zu erreichen (Sie werden sehen, dass ich damit Testsuiten lade, die in mehreren YAML-Dateien definiert sind und dass ich es als Liste von Includes für einentest:
Zielknoten funktionieren ließ ):Hier ist das Java einer Klasse, mit dem das
!include
Tag verarbeitet werden kann. Dateien werden aus dem Klassenpfad (Maven-Ressourcenverzeichnis) geladen:quelle
Mit Yglu können Sie andere Dateien wie folgt importieren:
A. yaml
B. yaml
Als
$import
Funktion können Sie auch einen Ausdruck als Argument übergeben:Dies würde die gleiche Ausgabe wie oben ergeben.
Haftungsausschluss: Ich bin der Autor von Yglu.
quelle
Mit Symfony können Sie durch die Behandlung von Yaml indirekt Yaml-Dateien verschachteln. Der Trick besteht darin, die
parameters
Option zu nutzen. z.B:common.yml
config.yml
Das Ergebnis ist das gleiche wie:
quelle
Wahrscheinlich wurde es nicht unterstützt, als eine Frage gestellt wurde, aber Sie können eine andere YAML-Datei in eine importieren:
Ich habe zwar keine Online-Referenz, aber das funktioniert für mich.
quelle
imports
.