Ich weiß also, dass ich so etwas tun kann:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
Und haben sitelist
und anotherlist
beide enthalten www.foo.com
und www.bar.com
. Was ich aber wirklich will, ist anotherlist
, auch zu enthalten www.baz.com
, ohne wiederholen zu müssen www.foo.com
und www.baz.com
.
Dadurch erhalte ich einen Syntaxfehler im YAML-Parser:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
- www.baz.com
Nur mit Ankern und Aliasnamen scheint es nicht möglich zu sein, das zu tun, was ich will, ohne eine weitere Ebene der Unterstruktur hinzuzufügen, wie zum Beispiel:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
Dies bedeutet, dass der Verbraucher dieser YAML-Datei sich dessen bewusst sein muss.
Gibt es eine reine YAML-Methode, um so etwas zu tun? Oder muss ich eine Post-YAML-Verarbeitung verwenden, z. B. das Implementieren einer Variablensubstitution oder das automatische Aufheben bestimmter Arten von Substrukturen? Ich mache bereits diese Art der Nachbearbeitung, um ein paar andere Anwendungsfälle zu behandeln, also bin ich nicht ganz abgeneigt. Aber meine YAML-Dateien werden von Menschen geschrieben und nicht maschinengeneriert. Daher möchte ich die Anzahl der Regeln minimieren, die meine Benutzer zusätzlich zur Standard-YAML-Syntax speichern müssen.
Ich möchte auch in der Lage sein, das Analoge mit Karten zu tun:
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
Ich habe die YAML-Spezifikation durchsucht und konnte nichts finden. Daher vermute ich, dass die Antwort nur "Nein, das können Sie nicht" lautet. Aber wenn jemand irgendwelche Ideen hat, wäre das großartig.
EDIT: Da es keine Antworten gab, gehe ich davon aus, dass niemand etwas entdeckt hat, was ich nicht in der YAML-Spezifikation habe, und dass dies auf der YAML-Ebene nicht möglich ist. Daher öffne ich die Frage für die Idee, die YAML nachzubearbeiten, um dies zu unterstützen, falls jemand diese Frage in Zukunft findet.
Antworten:
Der Typ des Zusammenführungsschlüssels ist wahrscheinlich das, was Sie wollen. Es verwendet einen speziellen
<<
Zuordnungsschlüssel, um Zusammenführungen anzuzeigen, sodass ein Alias für eine Zuordnung (oder eine Folge solcher Aliase) als Initialisierer für die Zusammenführung zu einer einzelnen Zuordnung verwendet werden kann. Darüber hinaus können Sie weiterhin Werte explizit überschreiben oder weitere hinzufügen, die nicht in der Zusammenführungsliste enthalten waren.Es ist wichtig zu beachten, dass es mit Zuordnungen funktioniert, nicht mit Sequenzen als erstes Beispiel. Dies ist sinnvoll, wenn Sie darüber nachdenken, und Ihr Beispiel sieht so aus, als müsste es wahrscheinlich sowieso nicht sequentiell sein. Das Ändern Ihrer Sequenzwerte in Zuordnungsschlüssel sollte den Trick tun, wie im folgenden (nicht getesteten) Beispiel:
Einige Dinge zu beachten. Erstens kann
<<
ein Schlüssel nur einmal pro Knoten angegeben werden , da er ein Schlüssel ist. Zweitens ist bei Verwendung einer Sequenz als Wert die Reihenfolge von Bedeutung. Dies spielt im Beispiel hier keine Rolle, da keine Werte zugeordnet sind, aber es lohnt sich, sich dessen bewusst zu sein.quelle
yaml.load(...)
in Python bin, bekomme ich ein Wörterbuch als Darstellung einer YAML-Zuordnung. Ja, es ist einfach, das in eine Menge nachzubearbeiten, aber ich muss wissen, dass dies passiert ist (und die semantische Komplexität beim Lesen / Schreiben der Konfigurationsdateien ist viel höher, wenn die Regel lautet: "Mengen werden als Karten mit Nullwerten geschrieben". ). Da ich eine Nachbearbeitung zwischenyaml.load(...)
und Verwendung der resultierenden Daten benötige, ob ich<<
oder verwendeMERGE
, bleibe ich wahrscheinlich beiMERGE
(was ich jetzt bereits implementiert habe).!!set
funktioniert. Zu viel obskures Boilerplate. Diese Dateien sind für Personen, die nicht unbedingt YAML-Experten sind, lesbar / lesbar. Die Leute werden ihre Site-Listen als YAML-Listen aufschreiben, sie dann zusammenführen und das Ganze in ein Set konvertieren müssen UND daran denken, es explizit als Set zu kennzeichnen ... Ich habe ein paar andere standardisierte Post- Dinge zusammen mitMERGE
sowieso verarbeiten. Vielen Dank für Ihre Hilfe!Wie die vorherigen Antworten gezeigt haben, gibt es keine integrierte Unterstützung für das Erweitern von Listen in YAML. Ich biete noch eine andere Möglichkeit, es selbst umzusetzen. Bedenken Sie:
Dies wird verarbeitet in:
Die Idee ist, den Inhalt eines Schlüssels, der mit einem '+' endet, mit dem entsprechenden Schlüssel ohne ein '+' zusammenzuführen. Ich habe dies in Python implementiert und hier veröffentlicht .
Genießen!
quelle
sites
und zusammenführtsites+
. Ich meine ein Tool, das vom Benutzer implementiert werden muss, da dies kein Standardverhalten istyaml
.(Beantwortung meiner eigenen Frage, falls die von mir verwendete Lösung für jeden nützlich ist, der in Zukunft danach sucht)
Da dies keine reine YAML-Methode ist, werde ich dies als "Syntaxtransformation" implementieren, die zwischen dem YAML-Parser und dem Code liegt, der die Konfigurationsdatei tatsächlich verwendet. Meine Kernanwendung muss sich also überhaupt nicht um menschenfreundliche Redundanzvermeidungsmaßnahmen kümmern und kann direkt auf die resultierenden Strukturen einwirken.
Die Struktur, die ich verwenden werde, sieht folgendermaßen aus:
Welches würde in das Äquivalent von umgewandelt werden:
Oder mit Karten:
Würde verwandelt werden in:
Noch formeller: Nachdem ich den YAML-Parser aufgerufen habe, um native Objekte aus einer Konfigurationsdatei abzurufen, aber bevor ich die Objekte an den Rest der Anwendung übergeben habe, durchsucht meine Anwendung das Objektdiagramm nach Zuordnungen, die den einzelnen Schlüssel enthalten
MERGE
. Der zugeordnete WertMERGE
muss entweder eine Liste von Listen oder eine Liste von Karten sein. Jede andere Unterstruktur ist ein Fehler.Im Fall der Listenliste
MERGE
wird die gesamte Karte, die sie enthält , durch die untergeordneten Listen ersetzt, die in der Reihenfolge miteinander verknüpft sind, in der sie angezeigt wurden.Im Fall der Kartenliste
MERGE
wird die gesamte Karte mit einer einzigen Karte ersetzt, die alle Schlüssel / Wert-Paare in den untergeordneten Karten enthält. Bei Überlappungen der Schlüssel wird der zuletzt in derMERGE
Liste vorkommende Wert aus der untergeordneten Zuordnung verwendet.Die oben angegebenen Beispiele sind nicht so nützlich, da Sie die gewünschte Struktur direkt hätten schreiben können. Es erscheint eher als:
So können Sie eine Liste oder Karte erstellen, die alles in Knoten enthält
salt
und anpepper
anderer Stelle verwendet wird.(Ich gebe immer wieder diese
foo:
äußere Karte, um zu zeigen, dassMERGE
dies der einzige Schlüssel in der Zuordnung sein muss, was bedeutet, dassMERGE
sie nicht als Name der obersten Ebene angezeigt werden kann, es sei denn, es gibt keine anderen Namen der obersten Ebene.)quelle
Um etwas aus den beiden Antworten hier zu verdeutlichen, wird dies nicht direkt in YAML für Listen unterstützt (es wird jedoch für Wörterbücher unterstützt, siehe Kittemons Antwort).
quelle
Beachten Sie, dass Sie Zuordnungen mit Nullwerten mithilfe der alternativen Syntax erstellen können, um die Antwort von Kittemon zu ändern
anstelle der vorgeschlagenen Syntax
Wie bei Kittemons Vorschlag können Sie auf diese Weise Verweise auf Anker innerhalb des Mappings verwenden und das Sequenzproblem vermeiden. Ich musste dies tun, nachdem ich festgestellt hatte, dass die Symfony Yaml-Komponente v2.4.4 die
? bar
Syntax nicht neu organisiert .quelle
myanchor
aus?