Entonces, sé que puedo hacer algo como esto:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
Y tienen sitelist
y anotherlist
ambos contienen www.foo.com
y www.bar.com
. Sin embargo, lo que realmente quiero es anotherlist
que contenga tambiénwww.baz.com
, sin tener que repetir www.foo.com
y www.baz.com
.
Hacer esto me da un error de sintaxis en el analizador YAML:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist: *sites
- www.baz.com
Simplemente usando anclas y alias, no parece posible hacer lo que quiero sin agregar otro nivel de subestructura, como:
sitelist: &sites
- www.foo.com
- www.bar.com
anotherlist:
- *sites
- www.baz.com
Lo que significa que el consumidor de este archivo YAML debe conocerlo.
¿Existe una forma pura YAML de hacer algo como esto? ¿O tendré que usar algún procesamiento posterior a YAML, como implementar la sustitución de variables o la elevación automática de ciertos tipos de subestructura? Ya estoy haciendo ese tipo de posprocesamiento para manejar un par de otros casos de uso, por lo que no soy totalmente contrario a él. Pero mis archivos YAML serán escritos por humanos, no generados por máquinas, por lo que me gustaría minimizar la cantidad de reglas que mis usuarios deben memorizar además de la sintaxis YAML estándar.
También me gustaría poder hacer lo análogo con los mapas:
namedsites: &sites
Foo: www.foo.com
Bar: www.bar.com
moresites: *sites
Baz: www.baz.com
Hice una búsqueda a través de la especificación YAML y no pude encontrar nada, por lo que sospecho que la respuesta es simplemente "no, no puedes hacer esto". Pero si alguien tiene alguna idea, sería genial.
EDITAR: Dado que no ha habido respuestas, supongo que nadie ha detectado nada que yo no haya visto en la especificación YAML y que esto no se puede hacer en la capa YAML. Así que estoy abriendo la pregunta a la idea de posprocesar el YAML para ayudar con esto, en caso de que alguien encuentre esta pregunta en el futuro.
Respuestas:
El tipo de clave de combinación es probablemente lo que desea. Utiliza una
<<
clave de mapeo especial para indicar fusiones, lo que permite utilizar un alias para un mapeo (o una secuencia de dichos alias) como inicializador para fusionar en un solo mapeo. Además, aún puede anular valores explícitamente o agregar más que no estaban presentes en la lista de combinación.Es importante tener en cuenta que funciona con asignaciones, no con secuencias como su primer ejemplo. Esto tiene sentido cuando lo piensa, y su ejemplo parece que probablemente no necesita ser secuencial de todos modos. Simplemente cambiar los valores de la secuencia a las claves de asignación debería funcionar, como en el siguiente ejemplo (no probado):
Algunas cosas para notar. En primer lugar, dado que
<<
es una clave, solo se puede especificar una vez por nodo. En segundo lugar, cuando se utiliza una secuencia como valor, el orden es significativo. Esto no importa en el ejemplo aquí, ya que no hay valores asociados, pero vale la pena tenerlo en cuenta.fuente
yaml.load(...)
en Python, obtengo un diccionario como representación de un mapeo YAML. Sí, es fácil posprocesar eso en un conjunto, pero tengo que saber que eso sucedió (y la complejidad semántica al leer / escribir los archivos de configuración es mucho mayor si la regla es "los conjuntos se escriben como mapas con valores nulos" ). Dado que necesito un posprocesamiento entreyaml.load(...)
los datos resultantes y su uso, ya sea que use<<
oMERGE
, probablemente me quedo conMERGE
(que ya he implementado ahora).!!set
funciona. Sin embargo, demasiada caligrafía oscura. Estos archivos están hechos para que los humanos puedan leer / escribir, por personas que no son necesariamente expertos en YAML. Las personas escribirán sus listas de sitios como listas YAML, luego querrán fusionarlas y tendrán que convertir todo en un conjunto Y recordar etiquetarlo explícitamente como un conjunto ... Tengo un par de otras publicaciones estandarizadas procesando cosas junto con deMERGE
todos modos. ¡Gracias por tu ayuda!Como han señalado las respuestas anteriores, no hay soporte integrado para extender listas en YAML. Ofrezco otra forma de implementarlo usted mismo. Considera esto:
Esto se procesará en:
La idea es fusionar el contenido de una clave que termina con un '+' con la clave correspondiente sin un '+'. Implementé esto en Python y publiqué aquí .
¡Disfrutar!
fuente
sites
ysites+
. Me refiero a una herramienta que debe ser implementada por el usuario ya que este no es unyaml
comportamiento predeterminado .(Responder a mi propia pregunta en caso de que la solución que estoy usando sea útil para cualquiera que busque esto en el futuro)
Sin una forma puramente YAML de hacer esto, voy a implementar esto como una "transformación de sintaxis" entre el analizador YAML y el código que realmente usa el archivo de configuración. Por lo tanto, mi aplicación principal no tiene que preocuparse en absoluto por ninguna medida de evitación de redundancia amigable para los humanos, y puede actuar directamente sobre las estructuras resultantes.
La estructura que voy a usar se ve así:
Que se transformaría en el equivalente de:
O, con mapas:
Se transformaría en:
Más formalmente, después de llamar al analizador YAML para obtener objetos nativos de un archivo de configuración, pero antes de pasar los objetos al resto de la aplicación, mi aplicación recorrerá el gráfico de objetos en busca de asignaciones que contengan la clave única
MERGE
. El valor asociado conMERGE
debe ser una lista de listas o una lista de mapas; cualquier otra subestructura es un error.En el caso de la lista de listas, todo el mapa que contiene
MERGE
será reemplazado por las listas secundarias concatenadas en el orden en que aparecieron.En el caso de la lista de mapas, el mapa completo que contiene
MERGE
será reemplazado por un solo mapa que contiene todos los pares clave / valor en los mapas secundarios. Cuando haya superposición en las claves,MERGE
se utilizará el valor del mapa secundario que aparece en último lugar en la lista.Los ejemplos dados anteriormente no son tan útiles, ya que podría haber escrito directamente la estructura que deseaba. Es más probable que aparezca como:
Permitiéndole crear una lista o mapa que contenga todo en los nodos
salt
y quepepper
se use en otros lugares.(Sigo dando ese
foo:
mapa externo para mostrar queMERGE
debe ser la única clave en su mapeo, lo que significa queMERGE
no puede aparecer como un nombre de nivel superior a menos que no haya otros nombres de nivel superior)fuente
Para aclarar algo de las dos respuestas aquí, esto no se admite directamente en YAML para listas (pero es compatible con diccionarios, consulte la respuesta de kittemon).
fuente
Para aprovechar la respuesta de Kittemon, tenga en cuenta que puede crear asignaciones con valores nulos utilizando la sintaxis alternativa
en lugar de la sintaxis sugerida
Como la sugerencia de Kittemon, esto le permitirá usar referencias a los anclajes dentro del mapeo y evitar el problema de la secuencia. Me encontré con la necesidad de hacer esto después de descubrir que el componente Symfony Yaml v2.4.4 no registra la
? bar
sintaxis.fuente
myanchor
parece?